简体   繁体   English

如何在 C++ 结构初始化中获取成员

[英]how to get the member in C++ struct initialization

struct Test {
    int w, h;
    int * p;
};

int main(){
    Test t {
        10,
        20,
        new int[this->h*this->w]
    };
    return 0;
}

I just want to use the w and h in initialization, is there any way to get this?我只想在初始化中使用 w 和 h,有什么办法可以得到这个吗?

First of all - you should avoid calling new (and delete ) explicitly , except in rare case;首先 - 你应该避免显式调用new (和delete ,除非在极少数情况下; this isn't one of them.这不是其中之一。 Use an std::unique_ptr to hold your allocated memory (see below).使用std::unique_ptr来保存您分配的 memory (见下文)。

To answer your question: You can't use the members of a struct/class as arguments to a constructor of that struct/class.要回答您的问题:您不能将结构/类的成员用作该结构/类的构造函数的 arguments。 Conceptually, the arguments are resolved before the constructor runs.从概念上讲,arguments 在构造函数运行之前被解析。

However, you can write a named constructor idiom:但是,您可以编写命名构造函数:

struct Test {
    int w, h;
    std::unique_ptr<int[]> p;

static:
    Test make(int w, int h) {
        return Test{ w, h, std::make_unique<int[]>(w*h) };
    }
};

which would let you write:这会让你写:

auto my_test = Test::make(w, h);

Alternatively, you could just outright implement a constructor which takes only w and h :或者,您可以直接实现一个只需要wh的构造函数:

struct Test {
    int w, h;
    std::unique_ptr<int[]> p;

    Test(int w_, int h_) : w(w_), h(_), p(std::make_unique<int[]>(w_*h_) { }
};

... but then you would need to write some extra code for a no-parameter constructor and a 3-parameter constructor (if not other methods). ...但是您需要为无参数构造函数和 3 参数构造函数(如果不是其他方法)编写一些额外的代码。

If you write a constructor for your class, you can take advantage of its member initializer list .如果您为 class 编写构造函数,则可以利用其成员初始化列表 In particular, you could exploit the fact that "non-static data member are initialized in order of declaration in the class definition" .特别是,您可以利用“非静态数据成员按 class 定义中的声明顺序初始化”这一事实。

Consider this little less trivial example考虑这个不那么琐碎的例子

#include <iostream>
#include <stdexcept>
#include <vector>

class Matrix
{
    int h_{};
    int w_{};
    std::vector<int> d_;
public:
    Matrix() = default;
    Matrix(int h, int w)
        : h_{checked_positive(h)}
        , w_{checked_positive(w)}
        , d_(h_ * w_)             // <-- 
    {}

    void show() {
        std::cout << h_ << ' ' << w_ << ' ' << d_.size() << '\n';
    }
private:
    int checked_positive(int d) {
        if (d < 1)
            throw std::runtime_error{"Dimensions must be positive"};
        return d;
    }
};

int main()
{
    Matrix a(3, 4);

    a.show();
}

Note, though, that some reviewers might find this dependency on the order of declaration of the members an unnecessary one and a maintainability cost.但请注意,一些审阅者可能会发现这种对成员声明顺序的依赖是不必要的,并且会增加可维护性成本。

In alternative, the dependent member could be default-initialized and then modified in the body of the constructor:或者,依赖成员可以默认初始化,然后在构造函数的主体中修改:

class Matrix
{
    std::vector<int> d_;  // <--
    int h_{}, w_{};
public:
    Matrix() = default;
    Matrix(int h, int w)
        : h_{checked_positive(h)}
        , w_{checked_positive(w)}
    {
        d_.resize(h_ * w_);   // <--
    }
// ...  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM