C++ 我可以从C+;中的另一个构造函数(进行构造函数链接)调用构造函数吗+;?
作为一名开发人员,我习惯于使用构造函数:C++ 我可以从C+;中的另一个构造函数(进行构造函数链接)调用构造函数吗+;?,c++,constructor,C++,Constructor,作为一名开发人员,我习惯于使用构造函数: public: StreamArrayReader(istream * in_stream); StreamArrayReader(char * filepath); // More constructors... 类测试{ 公开考试(){ DoSomething(); } 公共测试(int计数):this(){ DoSomethingWithCount(计数); } 公共测试(整数计数,字符串名称):此(计数){ dosome
public:
StreamArrayReader(istream * in_stream);
StreamArrayReader(char * filepath);
// More constructors...
类测试{
公开考试(){
DoSomething();
}
公共测试(int计数):this(){
DoSomethingWithCount(计数);
}
公共测试(整数计数,字符串名称):此(计数){
dosomethingwhithname(name);
}
}
在C++中有没有办法做到这一点?
<>我尝试调用类名,使用“这个”关键字,但是两个都失败了。 < p>如果我正确地理解了你的问题,你问你是否可以调用C++中的多个构造函数? 如果这就是你想要的,那么不,那是不可能的 当然,您可以有多个构造函数,每个构造函数都具有唯一的参数签名,然后在实例化新对象时调用所需的构造函数 您甚至可以有一个结尾带有默认参数的构造函数
但您可能没有多个构造函数,然后分别调用它们。
< P>不,在C++中,不能从构造函数调用构造函数。正如沃伦指出的,你能做的是:- 使用不同的签名重载构造函数
- 在参数上使用默认值,使“更简单”的版本可用
注意,在第一种情况下,不能通过从一个构造函数调用另一个构造函数来减少代码重复。当然,您可以使用一个单独的私有/受保护方法来完成所有初始化,并让构造函数主要处理参数处理。不,在C++03中,您不能从一个构造函数调用另一个构造函数(称为委托构造函数) 这在C++11(又名C++0x)中有所改变,它增加了对以下语法的支持:
(示例取自)
C++11:是的强> C++11及以后版本具有相同的功能(称为) 语法与C#略有不同: C++03:否 不幸的是,在C++03中无法做到这一点,但有两种方法可以模拟这一点:
class Foo {
public:
Foo(char x, int y=0); // combines two constructors (char) and (char, int)
// ...
};
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)
{
// ...
}
请参阅以供参考。C++11:是 C++11及以后版本具有相同的功能(称为) 语法与C#略有不同: C++03:否 值得指出的是,您可以在构造函数中调用父类的构造函数,例如:
class A { /* ... */ };
class B : public A
{
B() : A()
{
// ...
}
};
但是,不,在C++03之前不能调用同一类的另一个构造函数。我相信可以从构造函数调用构造函数。它将编译并运行。我最近看到有人这样做,它在Windows和Linux上都运行 它只是做不到你想要的。内部构造函数将构造一个临时本地对象,一旦外部构造函数返回,该对象将被删除。它们也必须是不同的构造函数,否则您将创建一个递归调用
参考:如果你想成为邪恶,你可以使用就地“新建”操作符:
class Foo() {
Foo() { /* default constructor deliciousness */ }
Foo(Bar myParam) {
new (this) Foo();
/* bar your param all night long */
}
};
似乎对我有用
编辑
正如@ElvedinHamzagic指出的,如果Foo包含分配内存的对象,那么该对象可能不会被释放。这使事情进一步复杂化
一个更一般的例子:
class Foo() {
private:
std::vector<int> Stuff;
public:
Foo()
: Stuff(42)
{
/* default constructor deliciousness */
}
Foo(Bar myParam)
{
this->~Foo();
new (this) Foo();
/* bar your param all night long */
}
};
class Foo(){
私人:
std::载体材料;
公众:
Foo()
:资料(42)
{
/*默认构造函数美味度*/
}
Foo(Bar myParam)
{
这个->~Foo();
新的(这个)Foo();
/*整晚都禁止你的情人*/
}
};
当然,看起来不那么优雅了@JohnIdol的解决方案要好得多。在a中:
此外,成员也可以这样初始化
class Foo {
int d = 5;
public:
Foo (int i) : d(i) {}
};
这将消除创建初始化助手方法的需要。仍然建议不要调用构造函数或析构函数中的任何虚拟函数,以避免使用任何可能未初始化的成员。另一个尚未显示的选项是将类拆分为两个,围绕原始类包装一个轻量级接口类,以实现您想要的效果:
class Test_Base {
public Test_Base() {
DoSomething();
}
};
class Test : public Test_Base {
public Test() : Test_Base() {
}
public Test(int count) : Test_Base() {
DoSomethingWithCount(count);
}
};
<>这可能会变得混乱,如果你有很多构造函数必须调用他们的“下一级”,但是对于少数的构造函数,它应该是可行的。 在VisualC++中,你也可以在构造函数中使用这个符号:-> CordNosi::Classname(另一个构造函数的参数)。请参见下面的示例:
class Vertex
{
private:
int x, y;
public:
Vertex(int xCoo, int yCoo): x(xCoo), y(yCoo) {}
Vertex()
{
this->Vertex::Vertex(-1, -1);
}
};
我不知道它是否在其他地方工作,我只在Visual C++ 2003和2008中测试过。我想,您也可以像在Java和C#中那样,以这种方式调用几个构造函数
旁白:坦白说,我很惊讶之前没有提到这一点。当调用构造函数时,它实际上从堆栈或堆分配内存。因此,在另一个构造函数中调用构造函数会创建本地副本。因此,我们正在修改另一个对象,而不是我们关注的对象。我建议使用
private friend
方法,该方法实现构造函数的应用程序逻辑,并由各种构造函数调用。以下是一个例子:
假设我们有一个名为StreamArrayReader
的类,其中包含一些私有字段:
private:
istream * in;
// More private fields
我们要定义两个构造函数:
public:
StreamArrayReader(istream * in_stream);
StreamArrayReader(char * filepath);
// More constructors...
其中第二个简单地使用了第一个(当然,我们不想重复前一个的实现)。理想情况下,人们希望做以下事情:
StreamArrayReader::StreamArrayReader(istream * in_stream){
// Implementation
}
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
StreamArrayReader(&instream);
instream.close();
}
但是,C++中不允许这样做。因此,我们可以如下定义一个私有friend方法,它实现了第一个构造函数应该做的事情:
private:
friend void init_stream_array_reader(StreamArrayReader *o, istream * is);
现在这个方法(因为它是朋友)可以访问o
的私有字段。然后,第一个构造函数变成:
StreamArrayReader::StreamArrayReader(istream * is) {
init_stream_array_reader(this, is);
}
请注意,这不会为新创建的副本创建多个副本。第二个是:
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
init_stream_array_reader(this, &instream);
instream.close();
}
Tha
private:
friend void init_stream_array_reader(StreamArrayReader *o, istream * is);
StreamArrayReader::StreamArrayReader(istream * is) {
init_stream_array_reader(this, is);
}
StreamArrayReader::StreamArrayReader(char * filepath) {
ifstream instream;
instream.open(filepath);
init_stream_array_reader(this, &instream);
instream.close();
}
Foo::Foo()
{
// do what every Foo is needing
...
}
Foo::Foo(char x)
{
*this = Foo();
// do the special things for a Foo with char
...
}
#include <iostream>
class A {
public:
A( int a) : m_a(a) {
std::cout << "A::Ctor" << std::endl;
}
~A() {
std::cout << "A::dtor" << std::endl;
}
public:
int m_a;
};
class B : public A {
public:
B( int a, int b) : m_b(b), A(a) {}
public:
int m_b;
};
int main() {
B b(9, 6);
std::cout << "Test constructor delegation a = " << b.m_a << "; b = " << b.m_b << std::endl;
return 0;
}
A::Ctor
Test constructor delegation a = 9; b = 6
A::dtor
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int)
};