首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何防止C++创建默认成员?

如何防止C++创建默认成员?
EN

Stack Overflow用户
提问于 2014-07-02 11:51:10
回答 7查看 148关注 0票数 1

假设我有以下课程:

代码语言:javascript
运行
复制
class A{
  ...
  B obj;
  C obj2
  ...
}

在构造A实例时,B obj将由默认构造函数初始化。但是在构造obj和obj2之前,我需要在A的构造函数中做一些计算,然后为B obj和C obj2调用一个非默认的构造函数。

这不需要花很多钱,但是在构造A时调用B obj和C obj2的默认构造函数是完全不必要的。

我能阻止C++调用默认构造函数吗?还是说这是错误的做法?

编辑:为了澄清,我添加了第二个对象。我必须从文件中读取,然后才能构造B和C。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2014-07-02 12:01:41

这是有点错误的做法。我建议你这样做:

代码语言:javascript
运行
复制
int arguments(){ //assuming obj takes an int as 3rd constructor argument, could be any
    //do computation you wanted to do in A::A
}

class A{
    A() : obj(non, Default, arguments()){}
    B obj;
}

现在初始化是在创建obj之前完成的。您还可以使arguments返回一个B并依赖于B的移动构造函数。

编辑:答案与编辑后的问题变化不大。现在有两个对象,但同样的逻辑适用于:

代码语言:javascript
运行
复制
class A{
    A() : obj(doInitCalculations()), obj2(something){}
    B obj;
    C obj2;
}

obj必须在obj2之前初始化(即使您编写了A() : obj2(), obj1{}),因为它们是按照类中声明的顺序构造的。因此,在构造任何一个对象之前,仍然会调用doInitCalculations

票数 4
EN

Stack Overflow用户

发布于 2014-07-02 12:02:07

您可以委托构造函数,类似于:

代码语言:javascript
运行
复制
class A
{
public:
    A() : A(ComputeSomethingForBAndC()) {}

private:
    A(const DataToBuildBAndC& dataToBuildBAndC) :
        b(dataToBuildBAndC),
        c(dataToBuildBAndC)
    {}
private:
  B b;
  C c;
};
票数 2
EN

Stack Overflow用户

发布于 2014-07-02 12:10:59

无论您做什么,在您进入B的主体之前,都将调用A的构造函数。如果没有在初始化程序列表中指定任何内容,则将调用默认构造函数。如果您需要先计算值,那么唯一的实际解决方案是在静态成员函数中这样做:

代码语言:javascript
运行
复制
class A
{
    B obj;
    static B initializeB( ... );
public:
    A( ... ) : obj( initializeB( ... ) ) {}
};

如果计算只依赖于参数,并且仅用于B的初始化,则这很好。否则,可能需要执行两次相同的计算。

如果B的初始化依赖于其他成员(这些成员也是计算出来的),那么您可以将其他成员放在obj之前(因此将首先初始化它们),并对它们使用静态成员技巧。(只需确保给出一个重要的注释,即您的代码完全取决于成员的顺序。)

最后,如果没有其他的工作,您可以为B安排一个“琐碎”的构造函数,该构造函数只执行最小值,以便以后的赋值能够工作。然后你可以写:

代码语言:javascript
运行
复制
A::A()
    : obj( doNothing )
{
    //  all the calculation
    obj = B(...);
}

(对于doNothing,只需使用枚举:

代码语言:javascript
运行
复制
enum DoNothing { doNothing };

)在B::B( DoNothing )中提供重载的B。)

我认为这是最后的手段,因为它涉及修改B,这是相当有侵略性的。不过,我以前也用过一两次。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24530404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档