【问题标题】:Can you construct after instantiation? Avoiding empty constructor实例化后可以构造吗?避免空构造函数
【发布时间】:2019-11-17 00:05:06
【问题描述】:

我有一个类,它的成员属性由在别处定义的对象组成。在下面的代码中,A 包含一个公共属性var,它是一个B

class B {
    public:
    int x, y;
    std::vector<int> z;
        B(int a, int b, std::vector<int> c) {
            x = a; y = b; z = c;
        }
};

class A {
    public:
        B var;
        A(int i, int j) {
            std::vector<int> someVector;
            B(i, j, someVector);
        }
};

int main() {
    A foo(5, 3);
    return 0;
}

这(显然)无法编译,因为 var 是在 A 的实例化时实例化的,为时已晚,无法构造它。

我能做类似事情的最好方法是修改一些代码:

class B {
    public:
    int x, y;
    std::vector<int> z;
        B() {}
        void setAttributes(int a, int b, std::vector<int> c) {
            x = a; y = b; z = c;
        }
};

class A {
    public:
        B var;
        A(int i, int j) {
            std::vector<int> someVector;
            B.setAttributes(i, j, someVector);
        }
};

这确实可以编译,因为属性是在实例化之后设置的。

但是有没有办法保持更接近第一个代码sn-p?

【问题讨论】:

标签: c++ class oop instantiation


【解决方案1】:
A(int i, int j) : var(i, j, {}) {}

另外,在您的代码B(i, j, someVector);初始化成员变量varB.setAttributes(i, j, someVector); 根本不会编译。

【讨论】:

    【解决方案2】:

    如果你不能定义一个有用的默认构造函数并且不想要丑陋的两步初始化,我想没有办法绕过指向 B 的指针。像

    #include <memory>
    
    class B {
        public:
            int x, y;
            std::vector<int> z;
    
            B(int a, int b, std::vector<int> c) {
                x = a; y = b; z = c;
            }
    };
    
    class A {
        public:
            std::unique_ptr<B> var;
            A() {
                std::vector<int> someVector;
                var = std::make_unique<B>(5, 2, someVector);
            }
    };
    
    int main() {
        A foo();
        return 0;
    }
    

    应该可以解决问题。

    【讨论】:

    • 在OP的代码中,构造var的所有必要数据都提供给A的构造函数,因此初始化可以在成员初始化列表中进行,如另一个答案所示,没有指针,两步初始化或默认构造函数。
    • 您在成员初始化方面是绝对正确的。我假设这只是一个非常小的示例,在现实世界的代码中,在将其传递给 B 之前,将在 A 的构造函数中的 someVector 中放入一些东西。关于类型别名......好吧......我会删除它。
    • 即使构造函数首先将东西放入向量中,仍然可以在初始化列表中的函数/lambda调用中完成。
    • 不错,没想到这么多。感谢您的反馈。
    猜你喜欢
    • 1970-01-01
    • 2019-01-24
    • 2011-05-08
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多