潍坊做网站的那家好,自媒体营销推广方案,网络营销软文案例,网店运营推广高级实训攻略目录
1. 问题引入
2. 4种implicitly声明的default constructor 1. 问题引入
“default constructors......在需要的时候被编译产生出来”。关键词是“在需要的时候”#xff0c;被谁需要#xff0c;做什么事情#xff1f;看看下面的代码#xff0c;然后梳理下思路。
cl…目录
1. 问题引入
2. 4种implicitly声明的default constructor 1. 问题引入
“default constructors......在需要的时候被编译产生出来”。关键词是“在需要的时候”被谁需要做什么事情看看下面的代码然后梳理下思路。
class Foo
{
public:int val;Foo *pnext;
};
void foo_bar()
{//程序要求bars members都被清空为0Foo bar;if(bar.val || bar.pnext)// ... do something//...
}
在上面的代码中正确的程序语意是要求Foo有一个default constructor可以将它的两个members初始化为0。然而“在需要的时候”答案是No其中的差别是一个被程序需要一个被编译器需要。程序如果需要那是程序员的责任本例中承担的责任是设计class Foo的人。是的上述的代码不会合成一个default constructor。
那么什么时候合成一个default constructorC Stand[ISO-C95]的Section2.1这么说对于class X如果没有任何的user-declared constructor那么会有一个default constructor 被implicitly隐式声明出来......一个被implicitly声明出来的default constructor 将是一个trivial没啥用的constructor。
下面分4种情况讨论default constructor 被implicitly声明出来。 2. 4种implicitly声明的default constructor
2.1带有default constructor的member class object
如果一个class没有任何的constructor但是它内含一个member object而后者有一个default constructor那么这个class 的implicit default constructor就是nontrivial编译器需要为该class合成一个default constructor。举个例子我们看看如下的代码在这个代码中Bar会合成一个default constructor。
class Foo{
public:Foo();Foo(int);
};
class Bar{
public:Foo foo;char *str;
};
void foo_bar(){Bar bar;//Bar::foo必须在此处初始化。//Bar::foo是一个member object而其//class Foo拥有default constructor符合要求if(bar.str){}....
}
扩张后的代码可能是这样子。
//扩张后的default constructor
//C伪码
Bar::Bar()
{foo.Foo::Foo();//附加上的compiler codestr 0;//explicit user code
}
2.2带有default constructor的Base Class
如果一个Base Class具有default constructor而这个基类的derived class没有default constructor此时derived class的default constructor会被视作nontrivial因此需要被合成出来。他将调用上一层base class的default constructor根据他们声明的顺序。 2.3“带有一个virtual function”的Class
另有两种情况也需要合成default constructor
Class 声明或继承一个virtual function。Class派生一个继承串链其中有一个或者更多的virtual base classes。
以下的程序为例子每个class object中一个额外的pointer member也就是vptr会被编译器合成出来内含class 的virtual function地址。Widegt要合成一个default constructorBell也要合成一个default constructorWhistle也要合成一个default constructor。
class Widget{
public:virtual void flip() 0;
};
void flip(const Widget widget)
{widget.flip();
}
class Bell:public Widget{
public:void flip(){coutBellendl;}
};
class Whistle:public Widget{
public:void flip(){coutWhistleendl;}
};
void foo()
{Bell b;Whistle w;flip(b);flip(w);
}
2.4“带有一个virtual base class”的Class
virtual base class的实现法在不同的编译器之间存在非常大的差异然而每一种实现法的共同点在于必须使得virtual base class在其每一个derived class object中的位置能够在执行期准备妥当。例如如下的代码代码中A,B,C均需要合成一个default constructor并在里面安插那些“允许每一个virtual base class的执行期存取操作”的代码。
class X {public: int i;};
class A:public virtual X{public: int j;};
class B:public virtual X{public: double d;};
class C:public A,public B{public: int k;};