【问题标题】:Circular dependency with classes that can be initialized one from another可以从另一个初始化的类的循环依赖
【发布时间】:2016-07-06 06:04:37
【问题描述】:

嗯,这个问题的正确标题应该是“类的循环依赖,实例可以从另一个初始化”。

我有两个类(带有整数数据字段的 Index3i 和带有浮点数据字段的 Index3f)意味着可以相互“转换”,反之亦然:

文件“Index3i.h”:

// #include "Index3f.h"

class Index3i {
public:
    Index3i()
    : r(0), g(0), b(0) { }

    Index3i(const Index3i& copy)
    : r(copy.r), g(copy.g), b(copy.b) { }

    // Index3i(const Index3f& copy)
    // : r((int)copy.r), g((int)copy.g), b((int)copy.b) { }

    // Index3f toIndex3f() { ... }

    ...
};

文件“Index3f.h”:

// #include "Index3i.h"

class Index3f {
public:
    Index3f()
    : r(0.0f), g(0.0f), b(0.0f) { }

    Index3f(const Index3f& copy)
    : r(copy.r), g(copy.g), b(copy.b) { }

    // Index3f(const Index3i& copy)
    // : r((float)copy.r), g((float)copy.g), b((float)copy.b) { }

    // Index3i toIndex3i() { ... }

    ...
};

我需要Index3i 类的对象能够初始化并转换为Index3f 类的对象,反之亦然。另外,我想只保留这些类的标题

好吧,如果我尝试取消注释已注释的构造函数、方法和包含,则会产生循环依赖问题。另一种可能的解决方案是实现一些转换函数并将它们放在第三个包含文件中,例如“IndexConvert.h”左右。

但也许还有其他方法?您能否建议我针对此案的适当解决方案?

【问题讨论】:

  • 我认为逻辑问题在这里,试图使您的 Index 类的浮动版本可降级。您应该支持升级到 float,但不支持降级到 int 版本。如果你想强制降级,你应该提供任何额外的功能。

标签: c++ class include circular-dependency member-initialization


【解决方案1】:

让它们都成为一个单一的类模板 - 听起来你实际上不需要从两个不同的类开始。这样,你就可以编写一个转换构造函数模板:

template <class T>
class Index3 {
    T r, g, b;

public:
    Index3() : r(0), g(0), b(0) { }
    Index3(const Index3&) = default;

    template <class U, class = std::enable_if_t<std::is_convertible<U, T>::value>>
    Index3(const Index3<U>& rhs)
    : r(rhs.r), g(rhs.g), b(rhs.b)
    { }

    /* rest */
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多