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?
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?
First of all - you should avoid calling new
(and delete
) explicitly, except in rare case; this isn't one of them. Use an std::unique_ptr
to hold your allocated memory (see below).
To answer your question: You can't use the members of a struct/class as arguments to a constructor of that struct/class. Conceptually, the arguments are resolved before the constructor runs.
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
:
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).
If you write a constructor for your class, you can take advantage of its member initializer list. In particular, you could exploit the fact that "non-static data member are initialized in order of declaration in the class definition".
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_); // <--
}
// ...