Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何处理没有默认构造函数但在另一个构造函数中构造的对象?_C++_Constructor_Default Constructor - Fatal编程技术网

C++ 如何处理没有默认构造函数但在另一个构造函数中构造的对象?

C++ 如何处理没有默认构造函数但在另一个构造函数中构造的对象?,c++,constructor,default-constructor,C++,Constructor,Default Constructor,我有以下示例代码 class ClassB { public: ClassB(int i); // No default constructor } class ClassA { ClassB obj; //NOT a pointer public ClassA() { //calculate someInt; obj = ClassB(someInt); // doesnt work } } 如何初始化ob

我有以下示例代码

class ClassB {
    public:
    ClassB(int i); // No default constructor
}

class ClassA {
    ClassB obj; //NOT a pointer
    public 
    ClassA() {
        //calculate someInt;
        obj = ClassB(someInt); // doesnt work
    }

}
如何初始化obj?
编译器抱怨
没有合适的默认构造函数可用于
obj

您在构造函数初始化列表中初始化成员。像这样:

ClassA() : obj(someInt) { }

您可以在构造函数初始化列表中初始化成员。像这样:

ClassA() : obj(someInt) { }

您的最佳设计解决方案是以如下方式初始化成员
obj

ClassA():obj(someInt){
但是,您的另一个选择是声明
ClassB
的默认构造函数,如下所示:

ClassB(){}
或者简单地让编译器使用以下命令为您创建一个:

ClassB()=默认值;
从C++标准中得出的结论是:

默认构造函数:编译器将定义隐式 默认构造函数,即使存在其他构造函数

如果选择第二个选项,则以下代码将不会出现错误:

#包括
B类{
公众:
ClassB()=默认值;
B类(国际一级);
};
甲级{
B类obj;
公众:
类别a(){
int-someInt=0;
obj=B类(someInt);
}
};
int main(){
返回0;
}
看看

结论

我强烈建议使用第一个选项,即带有初始化列表的选项,因为不需要先默认构造对象,然后再分配给它们。此外,这是没有赋值运算符的对象的唯一选项

更新1

解决此问题的另一种方法是在
ClassA
中使用
std::shared_ptr obj
,如下所示:

#包括
#包括
B类{
公众:
B类(国际一级);
};
甲级{
std::共享对象;
公众:
类别a(){
int-someInt=0;
obj=std::使_共享(someInt);
}
};
int main(){
返回0;
}
更新2

我想到的另一种可能性是在单独的函数中计算整数,然后将其作为初始化列表的一部分调用,如以下代码所示:

#包括
B类{
公众:
B类(国际一级);
};
甲级{
B类obj;
公众:
类别a()
:obj(计算())
{}
私人:
int计算(){
返回1;
}
};
int main(){
返回0;
}

查看它

您最好的设计解决方案是以如下方式初始化成员
obj

ClassA():obj(someInt){
但是,您的另一个选择是声明
ClassB
的默认构造函数,如下所示:

ClassB(){}
或者简单地让编译器使用以下命令为您创建一个:

ClassB()=默认值;
从C++标准中得出的结论是:

默认构造函数:编译器将定义隐式 默认构造函数,即使存在其他构造函数

如果选择第二个选项,则以下代码将不会出现错误:

#包括
B类{
公众:
ClassB()=默认值;
B类(国际一级);
};
甲级{
B类obj;
公众:
类别a(){
int-someInt=0;
obj=B类(someInt);
}
};
int main(){
返回0;
}
看看

结论

我强烈建议使用第一个选项,即带有初始化列表的选项,因为不需要先默认构造对象,然后再分配给它们。此外,这是没有赋值运算符的对象的唯一选项

更新1

解决此问题的另一种方法是在
ClassA
中使用
std::shared_ptr obj
,如下所示:

#包括
#包括
B类{
公众:
B类(国际一级);
};
甲级{
std::共享对象;
公众:
类别a(){
int-someInt=0;
obj=std::使_共享(someInt);
}
};
int main(){
返回0;
}
更新2

我想到的另一种可能性是在单独的函数中计算整数,然后将其作为初始化列表的一部分调用,如以下代码所示:

#包括
B类{
公众:
B类(国际一级);
};
甲级{
B类obj;
公众:
类别a()
:obj(计算())
{}
私人:
int计算(){
返回1;
}
};
int main(){
返回0;
}

查看它

你可以做
ClassA():obj(someInt){}
你可以做
ClassA():obj(someInt){}
我不推荐
ClassA(){int-someInt=0;obj=ClassB(someInt);}
。最好使用初始化列表而不是构造函数体,这样在分配给构造函数对象之前就不会不必要地默认构造函数对象。它也是没有赋值运算符的对象的唯一选项。@JesperJuhl我同意。这就是为什么我注意到初始化列表是更好的选择。我将更新我的答案,这也只是为了强调缺点。tnx当需要计算构造函数的参数时,如何将内容放入初始化列表中?在上面的例子中,
someInt
在编译时是未知的,我知道这一点。这就是为什么我也列出了第二种选择。如果要在计算整数值的同时使用初始化列表,则需要稍微更改设计。我不能向您推荐最佳选项,因为我不知道计算整数值背后的逻辑。另一种方法是使用
std::shared_ptr obj
成员。我知道我可以通过使用指针来避免整个问题。但那不是我想要的。初始化列表方法不起作用,因为