【问题标题】:C++ class member not initialized (at constructor, but does at initialize method)C++ 类成员未初始化(在构造函数中,但在初始化方法中)
【发布时间】:2015-01-15 08:29:32
【问题描述】:

我有一个带有两个构造函数的 C++ 类(一个默认构造函数,另一个带参数)。为了重用代码,我避免在构造函数级别初始化类成员,而是在 Initialize 方法中执行此操作,我从两个构造函数调用该方法。这样,我就想尽量减少代码行和重复代码:

Location::Location(){
    double pos[POSITION_SIZE] = {0};
    this->Initialize(const_cast<char*>(""), const_cast<char*>(""), pos);
}


Location::Location(char *id, char *code, double pos[POSITION_SIZE]){
    this->Initialize(id, code, pos);
}


void Location::Initialize(char *id, char *code, double pos[POSITION_SIZE]){
    strcpy(this->ID, id);
    strcpy(this->code, code);

    this->position[0] = pos[0];
    this->position[1] = pos[1];
    this->position[2] = pos[2];

    this->attribute1 = 0;
    this->attribute2 = 0;
}

标题:

class Location{
public:
    Location();
    Location(char *id, char *code, double pos[POSITION_SIZE]);

private:
    // This method initializes the location attributes given as parameters
    void Initialize(char *id, char *code, double pos[POSITION_SIZE]);

    // Name/identifier of the location
    char ID[ID_LENGTH];
    // FIR identifier
    char code[ID_LENGTH];
    // Location's coordinates (lat, lon, alt)
    double position[POSITION_SIZE];
    // Attribute 1
    double attribute1;
    // Attribute 2
    double attribute2;
};

我知道在使用时使用初始化方法是一种不好的做法,因为例如老式编码风格或避免在构造函数中使用异常。但是我的目标是减少代码,所以除非某些stackoverflow大师说相反,我认为这没有错(但我是来学习的,所以请摧毁我所有的信念)。

问题是我收到一个警告,因为我没有在 cosntructor 中初始化类成员。编译器不希望它们在 Initialize 方法中被初始化。那么,有什么方法可以让编译器开心吗?我应该忘记 aboput Initialize 方法的使用吗?

【问题讨论】:

  • 请显示类的声明 - 并认真考虑使用std::string 而不是摆弄 char* const_cast 和 strcpy(除非您使用一些没有字符串的奇怪标准库)。这段代码是在乞求问题。
  • @stijn 是的,我更喜欢 std::string,但遗憾的是,我继承了许多学习 C 而不是 C++ 的人编写的糟糕代码,我负担不起全部迁移。我现在会更新类声明
  • 在这里编译得很好(VS2013,gcc 4.8.3)——除了FIR没有在任何地方声明,我不得不猜测POSITION_SIZEID_LENGTH。请发布导致问题的确切代码并说明您的编译器/版本
  • @stijn 这不是问题,而是警告:“在此构造函数中未声明成员属性 1”。尝试将当前代码添加到给定示例时,FIR 是一个错字。确切的代码就是这样,有更多的类成员,它们都在 Initialize 方法中初始化。我只想知道如何避免警告消息(这是关于默认构造函数的属性 1 和关于另一个构造函数的属性 2,这很有趣),或者如果我在这里做了一些糟糕的实践,应该重新排列并忘记 Initialize方法
  • “未在此构造函数中声明”不会给出单个搜索命中。真的很想知道您使用的是什么编译器。

标签: c++


【解决方案1】:

我会使用构造函数委托,例如:

#include <iostream>
using namespace std;

class foo
{
public:
    foo()
    : foo(1, "2", 3.) // delegate to the other constructor with defaults...
    { }

    foo(int a, std::string b, double c)
    : _a(a), _b(b), _c(c)
    { }

private:
    int _a;
    std::string _b;
    double _c;
};

int main() {
    foo f1{};
    foo f2{1, "3", 4.};
    return 0;
}

请注意,您至少可以使用 c++11...

【讨论】:

  • 我不允许使用 C++11 :(。构造函数委托在 C++03 中可用吗?
  • 没有。不幸的是,没有干净的方法可以做到这一点,你有几个选择,所有这些仍然很乱,1.继承 - 将你所有的东西收集到一个基类中,然后使用基类构造函数,2. pimpl(隐藏你的实现和使用属性构造实现..) 等。
猜你喜欢
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
相关资源
最近更新 更多