`

拷贝构造函数的相互调用?

阅读更多
G++ error:
Error: declaration of xxx shadows parameter

Explanation:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3

[10.3] Can one constructor of a class call another constructor of the same class to initialize the this object?

Nope.

Let's work an example. Suppose you want your constructor Foo::Foo(char) to call another constructor of the same class, say Foo::Foo(char,int), in order that Foo::Foo(char,int) would help initialize the this object. Unfortunately there's no way to do this in C++.

Some people do it anyway. Unfortunately it doesn't do what they want. For example, the line Foo(x, 0); does not call Foo::Foo(char,int) on the this object. Instead it calls Foo::Foo(char,int) to initialize a temporary, local object (not this), then it immediately destructs that temporary when control flows over the ;.

class Foo {
public:
   Foo(char x);
   Foo(char x, int y);
   ...
};

Foo::Foo(char x)
{
   ...
   Foo(x, 0);  // this line does NOT help initialize the this object!!
   ...
}

You can sometimes combine two constructors via a default parameter:

class Foo {
public:
   Foo(char x, int y=0);  // this line combines the two constructors
   ...
};

If that doesn't work, e.g., if there isn't an appropriate default parameter that combines the two constructors, sometimes you can share their common code in a private init() member function:

class Foo {
public:
   Foo(char x);
   Foo(char x, int y);
   ...
private:
   void init(char x, int y);
};

Foo::Foo(char x)
{
   init(x, int(x) + 7);
   ...
}

Foo::Foo(char x, int y)
{
   init(x, y);
   ...
}

void Foo::init(char x, int y)
{
   ...
}

BTW do NOT try to achieve this via placement new. Some people think they can say new(this) Foo(x, int(x)+7) within the body of Foo::Foo(char). However that is bad, bad, bad. Please don't write me and tell me that it seems to work on your particular version of your particular compiler; it's bad. Constructors do a bunch of little magical things behind the scenes, but that bad technique steps on those partially constructed bits. Just say no.
分享到:
评论

相关推荐

    C++中拷贝构造函数的总结详解

    应该提供拷贝构造函数,并考虑重载`=赋值运算符`,确保"赋值运算符"遵循"右值不变性"(Right-Hand Side Value Semantics),即赋值后的左值对象和右值对象应能独立操作而不相互影响。 总的来说,理解和正确使用拷贝...

    八章节引用和拷贝构造函数PPT学习教案.pptx

    拷贝构造函数在以下情况会被调用: - 对象作为函数参数按值传递时。 - 对象作为函数返回值时。 - 对象用于初始化另一个对象时。 拷贝构造函数主要涉及成员变量的复制,对于复杂类型(如自定义类)的成员,通常需要...

    C++上机作业

    - **拷贝构造函数**:通过`StudentID`的拷贝构造函数实现深拷贝,确保对象间的独立性。 - **析构函数**:输出一条消息,表明析构函数被调用。 - **成员函数**:`setname()`, `setsex()`, `setbirthday()`用于设置...

    C++对象模型-322

    使用成员初始化列表比在构造函数体内赋值更有效,因为它可以避免多次调用默认构造函数或拷贝构造函数,并且对于`const`成员和引用成员,必须在初始化列表中初始化。 ### 第 3 章:Data 语意学 #### 3.1 Data ...

    C++设计模式-原型模式

    当一个对象被传递给函数或者作为返回值返回时,或者在一个对象被用作另一个对象的初始化器时,系统会自动调用拷贝构造函数。 ```cpp class Prototype { public: Prototype(const Prototype& other) { /* 拷贝构造...

    C++编程思想---我看过最好的关于c++分析的书籍(3)

    当一个对象被传递给函数、作为返回值或者赋值给另一个对象时,拷贝构造函数会被调用。理解和正确使用拷贝构造函数对于理解对象生命周期和深拷贝、浅拷贝的概念至关重要,也是防止意外数据共享和资源泄露的关键。 4....

    C++复习资料

    但是题目中并未涉及到拷贝构造函数的具体调用场景。 4. **构造函数的数量和参数**:一个类可以有多个构造函数,每个构造函数可以有任意数量的参数,包括零参数。 ### 友元 1. **友元类和友元函数**:友元关系使得...

    C++实验报告(1)[1].docx

    拷贝构造函数是在一个对象被用作另一个对象的初始值时调用,用于深拷贝或浅拷贝对象。 4. **友元函数和友元类**:友元函数是被允许访问类的私有和保护成员的非成员函数,而友元类的所有成员函数都可以访问另一个类...

    C++常见问题解答。。。。。。。。。

    在C++中,`std::list`是一个双向链表容器,当需要复制一个`std::list`对象时,拷贝构造函数会被调用。拷贝构造函数负责创建一个新的对象,并使新对象的内容与原始对象完全相同。 #### 23. 如何实现一个拷贝构造函数...

    面向对象程序设计期末复习题资料

    * 通常拷贝构造函数的参数是某个对象的引用名。 9. 纯虚函数 * 若在基类中将show声明为不带返回值的纯虚函数,正确的写法是virtual void show()=0; 10. C++语言 * C++语言是从早期的C语言逐渐发展演变而来的,...

    高质量C++编程指南

    - **处理拷贝构造函数与赋值函数的方法**:提供一种简化拷贝构造函数和赋值函数实现的方法。 - **派生类中实现基类函数**:在派生类中重写基类的构造函数、析构函数等。 - **心得体会**:作者关于构造函数、析构函数...

    高质量C++编程指南 超有用

    - **类STRING的拷贝构造函数与赋值函数**:同样以STRING类为例,介绍拷贝构造函数和赋值函数的具体实现。 - **处理拷贝构造函数与赋值函数的方法**:推荐的处理拷贝构造函数和赋值函数的方式。 - **派生类中实现基类...

    右值引用、移动语义和完美转发1

    而`AcceptRef()`通过常量左值引用接收对象,只调用了一次拷贝构造函数。如果使用`std::move()`,则可以进一步优化,实现移动构造,减少不必要的资源拷贝。 总的来说,右值引用和移动语义是C++11中提升程序效率的...

    新手学习C++入门资料

    上面例子中,第一次调用show()函数时,让编译器自动提供函数原型中指定的所有默认参数,第二次调用提供了第一个参数,而让编译器提供剩下的两个,第三次调用则提供了前面两个参数,编译器只需提供最后一个,最后一...

Global site tag (gtag.js) - Google Analytics