mtr*_*tha 4 c++ constructor raii
我来自Java背景,但之后我学习了C++并且已经用它编程了几年(主要是调试和编写修复程序,而不是从头开始设计程序).然而,我今天遇到了一个问题,坦率地说,我有点意外,花了很长时间才遇到它.
假设我有一个名为Class1的类,其头文件包含(以及其他代码):
class Class1 {
private:
Class2 object;
}
Run Code Online (Sandbox Code Playgroud)
Class2类没有指定默认构造函数.现在,在Class1构造函数中,我正在读取文件的二进制头文件,并使用我从中解析的信息来初始化Class2,如下面的伪代码所示:
Class1::Class1(std::string) {
// Read some binary info from a file here
// Parse that binary info
object2 = Class2(info);
Run Code Online (Sandbox Code Playgroud)
在Java中,由于它没有使用RAII范例,因此这是完全合法的.但是,由于C++使用RAII,因此在我执行时,对象2已经使用其默认构造函数进行了初始化object2 = Class2(info);.我原本不能调用那个构造函数(在Class1头文件中),因为我还没有创建我需要的信息object.但是,我不能只object2为构造函数创建局部,因为我需要其他函数才能看到/使用它.
显然这不起作用.这个东西的标准方法是什么?我实际上只是想把Class1改成像这样的Class2指针:
class Class1 {
private:
Class2* objectPointer;
}
Run Code Online (Sandbox Code Playgroud)
然后打电话*objectPointer = Class2(info).但是,在我的情况下,"Class2"是一个ifstream,似乎该operator=函数已被删除,并且不适用于任何一种方法.
那么......我该怎么做?
因为你object不是const,这完全合法.但是,如果要objects在初始化阶段初始化,则必须提供信息.你可以这样做
Class1::Class1(std::string file_name) : object(InfoFromFile(file_name)) {}
Run Code Online (Sandbox Code Playgroud)
where InfoFromFile()将是一个独立的函数(在.cc文件中的匿名命名空间中声明)或静态成员函数Class1.如果需要比file_name更多的信息来生成所需的信息Class2,则可以将其提供给该函数.
如果"读取和解析"部分不需要构造对象,那么您可以将其移动到静态(或非成员)函数,并使用以下结果初始化成员:
Class1::Class1(std::string) :
object2(read_class2_info(some_file))
{}
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因你真的无法将文件读取与对象构造分开,并且object2以后无法重新分配,那么你将需要使用指针.要创建对象,您可以使用new:
objectPointer = new Class2(info);
Run Code Online (Sandbox Code Playgroud)
但是,为了避免不得不乱用规则三,你应该避免自己管理动态对象,而是使用智能指针:
std::unique_ptr<Class2> objectPointer;
objectPointer.reset(new Class2(info));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
763 次 |
| 最近记录: |