c++ - 根据使用的构造函数声明一个成员

标签 c++

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_reffoo_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/

相关文章:

c++ - 编译 cpp 文件时出错 (ros)

c++ - 符号不能用在 using 声明中

c++ - C++ 中的欧拉方法;值变得太大太快

c++ - Hadoop流C++ getTaskId

c++ - iterator 和 const_iterator 之间的比较是否效率低下?

c++ - 从方法返回内部类时出错(C++)

c++ - 非返回 lambda,捕获作为函数指针

c++ - 一个只接受枚举类型参数的模板类?

c# - 对从托管代码创建的事件的 WaitForSingleObject 访问被拒绝

c++ - 从父类调用方法