变量引用和名称之间的区别

时间:2012-11-03 23:18:15

标签: c++ variables pointers reference

我正在研究c ++的参考,现在我对变量名和引用之间的区别感到很困惑。测试代码如下:

class TestClass{
private:
    int num;
public:
    TestClass(int n):num(n){
        cout<<this<<" : init of : " <<this->num<<endl;
    }

    TestClass(const TestClass& t):num(t.num){
        cout<<this<<" : copyInit of : " <<this->num<<endl;
    }

};

int main(int argc, const char * argv[]){

    TestClass t = *(new TestClass(55)); //just to test copy initialization

    const TestClass t2 = TestClass(100); //option1
    const TestClass &t2 = TestClass(100); //option2


}

所以现在我有两个制作对象的选项,它们彼此互斥。

根据我的理解,如果我使用 options2 ,编译器会在堆栈内存中生成一个临时对象,并将参考值返回给t2。

如果这是对的,我该如何用语言表达或解释 option1 ?似乎在堆栈内存中创建了相同的对象,并且计算机为该对象指定了名称“t2”,但我不清楚 option1 option2的不同之处因为变量和引用的名称有些令人困惑。

另外,交替切换选项,我可以看到在每种情况下都在不同的内存位置创建对象。 (例如,option1的对象是在0x7fff5fbff828中创建的,那个或option2是在0x7fff5fbff820中创建的)

请你解释一下

1。变量名(option1)和引用(option2)之间的区别是什么。

2。选项1和2中的工作原理有何不同。

3。为什么在任何一种情况下都会在不同的内存位置创建对象。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

const TestClass t2 = TestClass(100); //option1
const TestClass &t2 = TestClass(100); //option2

选项1:

调用TestClass的复制构造函数,并传入“=”右侧创建的临时文件。复制省略消除了不必要的对象复制(参见下面的Piotrs coment)。

选项2:

您创建了一个对象,即临时对象,该对象将被绑定到引用。

  
      
  1. 变量名(option1)和引用(option2)之间的区别是什么。
  2.   

编辑: 我之前不知道这一点,但事实上在选项1中没有第二次分配(感谢Piotr)这是由于复制elision引用了一种编译器优化技术,它消除了不必要的对象复制。

要使用您的文字,“变量名称”是包含数据的内存块。引用就像一个指针,它指向另一个“变量名”,但它必须初始化,并且永远不为null。

  
      
  1. 选项1和2中的工作方式不同。
  2.   

正如其他人所说,选项1是静态类型,其中选项2可以指向派生(来自TestClass)对象的实例。

  
      
  1. 为什么在任何一种情况下都会在不同的内存位置创建对象。
  2.   

尽管是“相同的”TestObjects(100),但它们是单独的实例,因此位于不同的内存(地址)中

答案 1 :(得分:1)

  

1)变量名(option1)和。之间的区别是什么   参考(选项2)。

名称具有静态类型。引用可以绑定到派生类 - 我们不知道引用对象的确切类型。

在您的示例中 - 对于选项2 - 您通过创建对它的const引用来延长临时对象的生命周期 - 请参阅http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

  

通常,临时对象只会持续到完全结束   它出现的表达方式。但是,C ++故意指定   将临时对象绑定到堆栈上对const的引用   延长临时寿命至终身寿命   引用自身,从而避免了本来会有的共同点   悬空参考错误。


  

2)选项1和2中的工作方式不同。

如果你调用虚函数 - 那么对于变量名你知道将调用哪个函数,对于引用 - 你不能在比你更复杂的例子中知道。


  

3)为什么在不同的内存位置创建对象   例。

它们是不同的对象,它们在同一时间生活 - 那么为什么它们的存储位置应该相同呢?

其他不同之处在于,对于选项1,您创建了自动变量,对于选项2,它是临时变量 - 两者都可能使用不同的内存(堆栈与寄存器或某些保留的内存仅用于临时变量)


考虑更复杂的例子:

class TestClass{
protected:
    int num;
public:
    TestClass(int n):num(n){
        cout<<this<<" : init of : " <<this->num<<endl;
    }
    TestClass(const TestClass& t):num(t.num){
        cout<<this<<" : copyInit of : " <<this->num<<endl;
    }
    virtual void printNum () const { cout << "NUM: " << num << endl; }
};

class TestClassDerived : public TestClass {
public:
    TestClassDerived(int n):TestClass(n){}
    virtual void printNum () const { cout << "DERIVED NUM: " << num << endl; }
};


int main(int argc, const char * argv[]){
    const TestClass t1 = TestClass(100); //option1
    const TestClass &t2 = TestClassDerived(100); //option2
    t1.printNum();
    t2.printNum();
}