struct foo
{
foo(int something) : m_something{ something } {}
foo() { }
private:
int m_something{};
};
struct bar
{
bar(foo& f)
:
m_foo{ f }
{ }
bar(int something)
:
m_default{ something } ,
m_foo{ m_default }
{
}
private:
foo m_default;
foo& m_foo;
};
bar 类可以通过引用 foo 来构造,也可以初始化 foo 本身。我想摆脱 m_default 的不必要的初始化成本,以防哪个 bar 是通过引用 foo 构造的。我知道它可以通过使用指针来解决,但我想留在堆栈中。
这可能吗?
Ted Lyngmo 的回答完美无缺。我正在分享完整代码:
#include <iostream>
struct foo;
struct foo_own;
// only holds a reference
struct foo_ref {
foo_ref(foo& fr) : m_foo(fr) {
std::cout << "foo_ref constructor is called\n";
}
virtual ~foo_ref() = default;
operator bool() { return false; }
operator foo&() { return m_foo; }
foo& operator*() { return m_foo; }
private:
foo& m_foo;
};
struct foo
{
foo(int something) : m_something{ something } {}
foo() { }
private:
int m_something{};
};
// owning a foo
struct foo_own : public foo_ref {
foo_own(int something) : foo_ref(m_default), m_default(something) {
std::cout << "foo_own constructor is called\n";
}
private:
foo m_default;
};
struct bar
{
bar(const foo_ref& f)
:
m_foo{ f }
{ }
bar(const foo_own& f)
:
m_foo{ f }
{ }
private:
const foo_ref& m_foo;
};
int main(int, char**) {
foo foo_l;
bar b{foo_l};
bar b2{15};
return 0;
}
输出是
foo_ref constructor is called
foo_ref constructor is called
foo_own constructor is called
最佳答案
你可以将它分为两种类型的 foo
包装器:
// only holds a reference
struct foo_ref {
foo_ref(foo& fr) : m_foo(fr) {}
virtual ~foo_ref() = default;
operator foo&() { return m_foo; }
foo& operator*() { return m_foo; }
private:
foo& m_foo;
};
// owning a foo
struct foo_own : public foo_ref {
foo_own(int something) : foo_ref(m_default), m_default(something) {}
private:
foo m_default;
};
为了避免将来的切片并有办法创建看起来非常相似的 foo_ref
和 foo_own
,您可以添加几个辅助函数:
auto make_foo_wrapper_ptr(foo& f) {
return std::make_unique<foo_ref>(f);
}
auto make_foo_wrapper_ptr(int v) {
return std::make_unique<foo_own>(v);
}
关于c++ - 根据使用的构造函数声明一个成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56118853/