📜  我们什么时候通过引用或指针传递参数?

📅  最后修改于: 2021-05-30 13:41:07             🧑  作者: Mango

在C++中,由于以下原因,变量通过引用传递:
1)修改调用者函数的局部变量:引用(或指针)允许被调用函数修改调用者函数的局部变量。例如,考虑以下示例程序,其中fun()能够修改main()的局部变量x

CPP
#include 
using namespace std;
 
void fun(int& x) { x = 20; }
 
int main()
{
    int x = 10;
    fun(x);
    cout << "New value of x is " << x;
    return 0;
}


C
class Employee {
private:
    string name;
    string desig;
 
    // More attributes and operations
};
 
void printEmpDetails(Employee emp)
{
    cout << emp.getName();
    cout << emp.getDesig();
 
    // Print more attributes
}


C
void printEmpDetails(const Employee& emp)
{
    cout << emp.getName();
    cout << emp.getDesig();
 
    // Print more attributes
}


C
#include 
#include 
 
using namespace std;
 
class Pet {
public:
    virtual string getDescription() const
    {
        return "This is Pet class";
    }
};
 
class Dog : public Pet {
public:
    virtual string getDescription() const
    {
        return "This is Dog class";
    }
};
 
void describe(Pet p)
{ // Slices the derived class object
    cout << p.getDescription() << endl;
}
 
int main()
{
    Dog d;
    describe(d);
    return 0;
}


C++
#include 
#include 
 
using namespace std;
 
class Pet {
public:
    virtual string getDescription() const
    {
        return "This is Pet class";
    }
};
 
class Dog : public Pet {
public:
    virtual string getDescription() const
    {
        return "This is Dog class";
    }
};
 
void describe(const Pet& p)
{ // Doesn't slice the derived class object.
    cout << p.getDescription() << endl;
}
 
int main()
{
    Dog d;
    describe(d);
    return 0;
}


C++
#include 
using namespace std;
 
class base {
public:
    virtual void show()
    { // Note the virtual keyword here
        cout << "In base \n";
    }
};
 
class derived : public base {
public:
    void show() { cout << "In derived \n"; }
};
 
// Since we pass b as reference, we achieve run time
// polymorphism here.
void print(base& b) { b.show(); }
 
int main(void)
{
    base b;
    derived d;
    print(b);
    print(d);
    return 0;
}


输出:
x的新值为20

2)对于传递大型参数:如果参数较大,则通过引用(或指针)传递效率更高,因为仅实际传递地址,而不传递整个对象。例如,让我们考虑以下Employee类和一个用于打印Employee详细信息的函数printEmpDetails()

C

class Employee {
private:
    string name;
    string desig;
 
    // More attributes and operations
};
 
void printEmpDetails(Employee emp)
{
    cout << emp.getName();
    cout << emp.getDesig();
 
    // Print more attributes
}

上面的代码存在的问题是:每次调用printEmpDetails()时,都会构造一个新的Employee对象,其中涉及创建所有数据成员的副本。因此,更好的实现方法是将Employee作为参考。

C

void printEmpDetails(const Employee& emp)
{
    cout << emp.getName();
    cout << emp.getDesig();
 
    // Print more attributes
}

这一点仅对结构和类变量有效,因为我们对于int,char等基本类型没有任何效率优势。

3)为避免对象切片: 如果我们将子类的对象传递给需要超类对象的函数,则按值传递的对象将被切片。例如,考虑以下程序,它打印“ This is Pet Class”。

C

#include 
#include 
 
using namespace std;
 
class Pet {
public:
    virtual string getDescription() const
    {
        return "This is Pet class";
    }
};
 
class Dog : public Pet {
public:
    virtual string getDescription() const
    {
        return "This is Dog class";
    }
};
 
void describe(Pet p)
{ // Slices the derived class object
    cout << p.getDescription() << endl;
}
 
int main()
{
    Dog d;
    describe(d);
    return 0;
}

输出:
这是宠物课
如果我们在上述程序中使用按引用传递,则它会正确打印“ This is Dog Class”。请参阅以下修改的程序。

C++

#include 
#include 
 
using namespace std;
 
class Pet {
public:
    virtual string getDescription() const
    {
        return "This is Pet class";
    }
};
 
class Dog : public Pet {
public:
    virtual string getDescription() const
    {
        return "This is Dog class";
    }
};
 
void describe(const Pet& p)
{ // Doesn't slice the derived class object.
    cout << p.getDescription() << endl;
}
 
int main()
{
    Dog d;
    describe(d);
    return 0;
}

输出:
这是狗班
这一点对于基本数据类型(例如int,char等)也无效。

4)在函数实现运行时多态 
我们可以通过将对象作为对其的引用(或指针)进行传递来使函数变为多态。例如,在以下程序中,print()接收对基类对象的引用。如果传递了基类对象,则print()调用基类函数show();如果传递了派生类对象,则调用派生类函数show()。

C++

#include 
using namespace std;
 
class base {
public:
    virtual void show()
    { // Note the virtual keyword here
        cout << "In base \n";
    }
};
 
class derived : public base {
public:
    void show() { cout << "In derived \n"; }
};
 
// Since we pass b as reference, we achieve run time
// polymorphism here.
void print(base& b) { b.show(); }
 
int main(void)
{
    base b;
    derived d;
    print(b);
    print(d);
    return 0;
}
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”