C ++构造函数调用和对象创建 [英] C++ constructor calling and object creation

查看:113
本文介绍了C ++构造函数调用和对象创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class Test{
    public :
        int x;  
        Test()
        {
            x = 0;
            cout<<"constructor with no arguments called"<<endl;
        }
        Test(int xx)
        {
            x = xx;
            cout<<"constructor with single int argument called"<<endl;
        }
        
};


int main()
{
    Test a(10);
    Test aa = 10;
}

输出:
程序编译并输出

output: Program compiles and outputs


具有单个int参数的构造函数

constructor with single int argument called

具有单个int参数的构造函数称为

constructor with single int argument called

但是现在

class Test{
    public :
        int x;  
        Test()
        {
            x = 0;
            cout<<"constructor with no arguments called"<<endl;
        }
        Test(int xx)
        {
            x = xx;
            cout<<"constructor with single int argument called"<<endl;
        }
        
        Test( Test& xx)
        {
            x = xx.x;
            cout<<"copy constructor called"<<endl;
        }
        
        
};


int main()
{
    Test a(10);
    Test aa = 10;
}

编译失败。

constructorinvokings.cc:36:7: error: no viable constructor copying variable of type 'Test'
        Test aa = 10;
             ^    ~~
constructorinvokings.cc:23:3: note: candidate constructor not viable: no known conversion from 'Test' to 'Test &' for 1st
      argument
                Test( Test& xx)
                ^
1 error generated.

我是C ++的新手。

不测试a(10)并测试aa = 10;相同吗?

Aren't Test a(10) and Test aa = 10; identical ?

为什么将复制构造函数与Test aa = 10冲突?

why is the addition of copy constructor conflicting with Test aa=10?

如果我将Test(Test& xx)修改为Test( const Test& xx)它正在工作。但是,当我们尝试使用整数参数调用构造函数时,为什么编译器会检查复制构造函数签名。

if I modify Test(Test& xx) to Test(const Test& xx) it is working. But why is the compiler checking for copy constructor signature when we are trying to call constructor with integer argument.

请先弄清楚

谢谢。 / p>

Thanks in advance.

推荐答案

到目前为止,您所获得的所有答案都过于复杂和/或具有误导性。

All of the answers you've gotten so far are overly complicated and/or slightly misleading.

在第一次构造/初始化中:

In the first construction/initialization:

T a(10);

非常明显的事情发生了。第二种构造/初始化更有趣:

The very obvious thing happens. The second construction/initialization is more interesting:

T aa = 10;

这等效于:

T aa(T(10));

意思是创建一个T类型的临时对象,然后构造 aa 作为此临时文件的副本。

Meaning that you create a temporary object of type T, and then construct aa as a copy of this temporary. This means that the copy constructor is called.

C ++有一个默认的复制构造函数,当您没有显式声明的时候,它会为一个类创建一个默认的复制构造函数。因此,即使 class T 的第一个版本没有声明副本构造函数,也仍然有一个。编译器声明的那个具有此签名 T(const T&)

C++ has a default copy constructor that it creates for a class when you have none explicitly declared. So even though the first version of class T has no copy constructor declared, there still is one. The one the compiler declares has this signature T(const T &).

现在在第二种情况下,您声明类似于复制构造函数的东西,则将参数设为 T& ,而不是 const T& 。这意味着编译器在尝试编译第二个表达式时会尝试使用您的副本构造函数,而不会。有人抱怨您声明的副本构造函数需要一个非const参数,而给出的参数是const。

Now in your second case where you declare something that looks like a copy constructor, you make the argument a T &, not a const T &. This means that the compiler, when trying to compile the second expression, tries to use your copy constructor, and it can't. It's complaining that the copy constructor you declared requires a non-const argument, and the argument it's being given is const. So it fails.

另一条规则是,在编译器将您的初始化转换为 T aa(T(10)); ,然后将其转换为 T aa(10); 。这称为复制省略。在某些情况下,允许编译器跳过对复制构造函数的调用。但是,只有在验证了表达式的格式正确并且在复制构造函数调用仍然存在时不会产生任何编译器错误之后,它才能执行此操作。因此,这是一个优化步骤,可能会准确影响程序的哪些部分运行,但不会影响哪些程序有效和哪些程序出错(至少从它们是否编译的角度来看)。

The other rule is that after the compiler has converted your initialization to T aa(T(10)); it is then allowed to transform it to T aa(10);. This is called 'copy elision'. The compiler is allowed, in certain circumstances, to skip calls to the copy constructor. But it may only do this after it verifies that the expression is correctly formed and doesn't generate any compiler errors when the copy constructor call is still there. So this is an optimization step that may affect exactly which parts of a program run, but cannot affect which programs are valid and which ones are in error (at least from the standpoint of whether or not they compile).

这篇关于C ++构造函数调用和对象创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆