Des*_*tor 15 c++ variadic-functions copy-constructor
考虑以下程序:
#include <iostream>
struct Test
{
int a;
Test() : a(3)
{ }
Test(const Test& t...)
{
std::cout<<"Copy constructor called\n";
a=t.a;
}
int get_a()
{
return a;
}
~Test()
{
std::cout<<"Destructor is called\n";
}
};
int main()
{
Test t;
Test* t1=new Test(t);
std::cout<<t.get_a()<<'\n';
std::cout<<t1->get_a()<<'\n';
delete t1;
}
Run Code Online (Sandbox Code Playgroud)
仔细观察复制构造函数参数中的三个点我尝试这个程序时真的很惊讶.有什么用?这是什么意思?
语言规范对此有何看法?
我知道三个点用于表示变量函数(如等)中的变长参数printf()以及scanf()C99引入的可变参数宏.在C++中,如果我没有错,它们将用于可变参数模板.
这段代码是否形成良好?这个可变参数构造函数是否可以使用任意数量的参数?
它在g ++ 4.8.1和MSVS 2010上编译并运行良好.
在节中的标准草案8.3.5 [dcl.fct]说, ...是同义词...,除非...是抽象的说明符(部分重点矿山):
[...]如果参数声明子句以省略号或函数参数包(14.5.3)结束,则参数的数量应等于或大于没有默认参数的参数的数量,不是函数参数包.在语法正确且"......"不是抽象声明者的一部分的地方,",......"与"......"同义.[...]
所以它是一个可变函数,据我所知,没有额外的参数,这也是一个有效的拷贝构造函数,来自12.8 [class.copy]部分:
如果X类的第一个参数是X&,const X&,volatile X&或const volatile X&,并且没有其他参数或者所有其他参数都有默认参数,则类X的非模板构造函数是一个复制构造函数(8.3.6) ).
并且这个说明说椭圆不是参数:
Run Code Online (Sandbox Code Playgroud)void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow // a parameter with a default argument
由上面的规范性文本支持,其中说:
如果参数声明子句以省略号终止[...]
注意,因为有人要求抽象声明符是没有标识符的声明符.
有什么用?这是什么意思?
是的,它引入了一个可变函数.
在C++中如果我没有错,它们将用于可变参数模板.
语法和语义不同.它是一种"C风格"的可变参数函数,而不是可变参数模板函数.此外,复制构造函数不能是模板函数.
如果X类的第一个参数是X&,const X&,volatile X&或const volatile X&,并且没有其他参数或者所有其他参数都有默认参数,则类X的非模板构造函数是一个复制构造函数(8.3.6) ).
最终草案中的§12.8.2(强调我的)
这段代码是否形成良好?这个可变参数构造函数是否可以使用任意数量的参数?
如果省略号包含参数,它不再是复制构造函数,而是一个简单的构造函数.如果没有,则它是有效的复制构造函数.
X(const X&, int = 1, double = 5); // copy-ctor
X(const X&, int = 1, double); // constructor
Run Code Online (Sandbox Code Playgroud)