【问题标题】:C++ constructor init multiple membersC++构造函数初始化多个成员
【发布时间】:2014-05-02 09:40:58
【问题描述】:

鉴于这个类:

void calculate( int*, int* );

struct A{
    int p;
    int q;
    A() { calculate( &p, &q ); }
};

我想让成员pq 保持不变:

struct A{
    const int p;
    const int q;
    // constructor???
};

问题是,如何初始化这些值?我想从构造函数中调用calculate,或者可能是某种代理函数,但是我怎样才能以一种同时初始化两个值的方式来做到这一点?一个明显的想法是构造函数的包装器:

A create_A(){
    int p0;
    int q0;
    calculate( &p0, &q0 );
    return A{ p0, q0 };
}

但这让我没有合适的默认构造函数。很不方便。有没有办法用默认构造函数来完成这个?

只是为了好玩,我实际上发现了这个,它可以满足我的需要,但并不是一个真正可行的选择,因为它不是线程安全的:

int foo( bool b )
{
    static int p;
    static int q;
    if( b ){
        calculate( &p, &q );
        return p;
    } else {
        return q;
    }
}

struct A{
    const int p;
    const int q;
    A() : p( foo( true ) ), q( foo( false ) ){}
};

编辑很多人抱怨我使用const 会员。但是这个问题在 const 成员之外很有趣,在我的特定用例中 pq 不是 int 而是一些没有默认构造函数的类类型,所以我需要使用成员初始化语法,即使它们不是常量。哦,当然 const 成员确实有优势:更快的调试模式、更少的抽象层、更少的复杂性、更多的编译器强制不变量。

【问题讨论】:

  • const 成员是个坏主意。这只是您会遇到的许多令人头疼的问题之一。最好只公开const 访问器。
  • @DeadMG 我想到的唯一另一个问题是缺少赋值运算符,我可以不用它。你能想到我应该期待的其他问题吗?

标签: c++ constructor initialization


【解决方案1】:

从你的辅助函数返回一个结构,并将构造委托给另一个构造函数,如下所示:

#include <utility>
std::pair<int,int> calculate();

struct A{
    const int p;
    const int q;
    A() : A(calculate()) {}
private:
    A(std::pair<int,int> a) : p(a.first), q(a.second) {}
};

委派构造函数自 C++11 起就已成为标准,尽管它们以前在许多编译器中都可以使用,因为它们是语义上未定义的构造。

不过,这会禁用赋值运算符。你确定内联const-qualified 访问器不是一个更好的主意吗?它们没有运行时开销。

【讨论】:

  • const 限定的访问器在调试模式下确实有运行时开销,这是我大部分时间使用的。而且它们在整体代码大小方面存在开销。
  • 嗯,也许是没有优化的调试模式。但这不是您测量的模式,是吗?无论如何,这也适用于标准库。
  • 我只是讨厌它必须等待永远让调试器到达某个位置。而且我更喜欢浅堆栈而不是深度嵌套的堆栈。每个人都不行吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 2020-09-30
  • 2011-05-02
相关资源
最近更新 更多