2009-12-22 56 views
8

在为我的某个类(包含其他UDT的几个对象)编写复制构造函数时,我需要为这些UDT创建一个默认构造函数,即使它们并非真正意图有一个。如何处理必需的默认构造函数

仅仅实现一个空白的默认构造函数并完成它就可以了吗?调用默认构造函数的唯一时间是在此复制期间,创建对象时,然后将相应对象的值复制到其中。因此,无论在默认构造函数中分配给对象的值都不会实际使用。

我看到的问题是某些成员变量未在空白默认构造函数中初始化。我应该只写一个给出虚拟值的东西吗?任何其他建议的方式来处理这个?

编辑:据我所知,复制构造函数不需要一个默认构造函数,如果我要为其他类定义复制构造函数,但我没有,所以它确实需要它。

+0

欢迎来到StackOverflow!伟大的第一个问题 – Sampson 2009-12-22 17:08:48

+0

这将是一个更好的例子代码。 – 2009-12-22 17:40:44

回答

5

如果您在拷贝构造函数使用初始化列表,你并不需要一个默认的构造函数:在

#include <iostream> 
using namespace std; 
class Foo { 
    Foo();   /* no default constructor */ 
public: 
    Foo(int i)  { cout << "Foo constructor (int)" << endl; } 
    Foo(const Foo& f) { cout << "Foo constructor (copy)" << endl; } 
}; 
class Bar { 
    Foo f; 
public: 
    Bar()    : f(1) { cout << "Bar constructor (default)" << endl; } 
    Bar(const Bar& b) : f(b.f) { cout << "Bar constructor (copy)" << endl; } 
}; 
int main(void) { 
    Bar b; 
    Bar b_=b; 
    return 0; 
} 

结果:

Foo constructor (int) 
Bar constructor (default) 
Foo constructor (copy) 
Bar constructor (copy) 
+0

这两个类都具有复制构造函数以外的构造函数。而你所说的是不正确的。 – 2009-12-22 17:30:04

+0

这是一个很奇怪的声明。在当前的C++中,你不能从另一个构造函数中“调用”一个构造函数。因此,如果使用复制构造函数,无论使用初始化列表还是不使用默认构造函数(这根本不可能)。 – AnT 2009-12-22 17:32:00

+0

原始示例中的要点是Foo的默认构造函数未被复制调用。我编辑了这个例子来删除Foo的默认构造函数,以更好地说明这一点。这些类显然具有复制构造函数以外的构造函数 - 您还将如何创建该对象的第一个实例?我的理解是,目标是避免添加不需要的默认构造函数。 – mrkj 2009-12-22 17:36:15

2

你说:相应的对象 的

创建对象时

,然后 的值复制到它。

但问问自己 - 那个“相应的对象”的值是如何到达那里的。即相应的对象是如何创建的?

This previous SO discussion可能有助于为您澄清问题。

4

你确定你确实需要一个拷贝构造函数吗?有一个类默认的构造函数可以,但是你需要一个自定义的拷贝构造函数是很不寻常的(但并非不可能)。也许你可以发布你的班级的代码?

+0

是的,因为我需要进行深层复制。 – Anonymous 2009-12-22 18:04:19

+0

C++并未真正使用术语“深层复制” - 如果您发布了一些代码,事情会更加清晰。 – 2009-12-22 18:08:09

+0

那么如果它不被称为深度复制,那么它是什么? – Anonymous 2009-12-22 19:12:07

1

这听起来不像实现复制构造函数的最佳方式。如果包含的类型本身提供了拷贝构造函数 - 使用它们。毕竟,类型不提供默认的构造函数可能是有原因的。

1

我会先问为什么那些复制的UDT涉及默认构造函数,而不是更合适拷贝构造函数。我还想问一下,如果物体的确有意义,那么物体在默认初始化状态—意味着什么意思,然后通过一切手段实现它。

如果您对默认初始化没有合理的意义,并且您绝对必须使用默认构造函数定义对象,那么我认为可以实现默认构造函数。

但是,并非所有对象都可以获得默认的构造函数,因此修复问题的源代码仍然是一个好主意。

0

您可以通过要求另一个对象也有复制构造函数来阻止默认构造函数(或者使用特殊的构造函数来传递构造对象所需的所有信息,通常具有不初始化所有成员变量的默认构造函数是非常糟糕的想法。至少要确保其他类的默认构造函数初始化所有成员。

3

这听起来像你需要为其他类定义副本c'tors,因为你通过复制其他对象来创建它们的对象。

0

记住拇指规则,尽可能的东西不是规范的一部分,编译器不会为你做。

如果您的类包含用户定义的类型,并且在创建它的对象时,编译器必须调用每个对象的默认构造函数。

但是,初始化对象的数据成员不是编译器的任务,但你应该这样做。

对于您提到的情况,您需要您自己的自定义副本构造函数和赋值运算符。

0

如果你不想让编译器生成一个拷贝构造函数或者根本不想拷贝构造函数,那么声明一个私有拷贝构造函数,但是不要为它提供任何定义(代码)。编译器将看到声明并且不会生成声明。也可以通过赋值运算符来完成。

我这样做与我的单身人士班。

0

如果您的类不是默认构造的,请不要创建默认构造函数。 如果是这样,那么我相信你可以找出一个合理的初始化,所以这就是你应该使用的。

0

问题,你说的方式似乎没有意义。你似乎相信复制构造函数不需要默认的构造函数。复制构造函数是一个完全独立的完全构造函数,它自己完全构造一个对象。

如果使用copy-constructor构造对象,则不需要默认的对象。如果使用默认构造函数构造对象,则不能在其上使用复制构造函数。将两个不同的构造函数“应用”到同一个对象是不可能的。

如果你用两种方式构造你的对象,那么它们将成为两个完全独立的构造函数,每个构造函数都有其独立的目的。在这种情况下,你应该问自己的问题是如何想要你的对象被构​​造。只有你知道这一点。

同样,你需要澄清你的问题。我会怀疑(从你的描述中)你试图实现的不是复制构造函数,而是复制赋值操作符。但这只是一个疯狂的猜测。