从没有 reinterpret_cast 的向前声明的同级构建 parent

Construct parent from forward declared sibling without a reinterpret_cast

我正在尝试调用 parent 构造函数,并使用给定的指向同级 object:

的指针
class Base{
public:
    Base(const Base&) =default;    
};

#include "daughter.h"     // <-- problem! I'll come to this in a second.

class Son: public Base{
public:
    Son(Daughter* d) : Base(*d){};
};

但是(问题来了),这种关系是双向的:

// daughter.h
class Son;               // forward declare needed
class Daughter: public Base{
public:
    Daughter(Son* s) : Base(*d){};
};

Uh-oh: (link to run)

error: no matching function for call to 'Daughter::Daughter(Base&)'

note: candidates are:

note: Daughter::Daughter(const Base&)

note: no known conversion for argument 1 from 'Daughter' to 'const Base&'

所以,问题出现了,因为那时 - Son 是一个不完整的类型 - 不知道它继承自 Base,因此这个构造函数不匹配。

我已经可以'solve'了:

Daughter::Daughter(Son* s) : Base( *reinterpret_cast<Base>(*s) ){};

但这似乎是不好的做法 - 我不认为我应该 reinterpret_cast 为如此无辜的意图 - 我们都知道 Son 将是 Base!

的派生 class

有没有更好的方法来处理这个问题?

注意: 虽然它可能确实来自糟糕的整体设计 - “[我] 不需要从兄弟姐妹那里构建一个 parent。” - 请记住,我 已经 将这个从一个更大的设计(有更多的兄弟姐妹,每个兄弟姐妹都有更多的构造函数)中减少到一个非常小的例子,其中这样做是必要的几个地方。

您的 类 是循环依赖的。如果将定义移到 类 的定义后面,则可以解决 "incomplete class" 问题。

注意定义只能定义一次,或者定义inline.

#include <string>
#include <iostream>
#include <list>
#include <vector>

class Base{
public:
    Base(const Base&) =default;
};

class Son;
class Daughter: public Base{
public:
    Daughter(Son* s);
};

class Son: public Base{
public:
    Son(Daughter* d);
};

Son::Son(Daughter* d) : Base(*d){};
Daughter::Daughter(Son* s) : Base(*s){};

int main(){
}

(这并没有解决其他问题 - 这个设计很糟糕)

您必须在 cpp 文件中定义构造函数以打破循环依赖:

// base.h
class Base {
public:
    Base(const Base& b) { ... }
};

// son.h
#include "base.h" // include because you need the definition for inheritance
class Daughter;   // don't include, just forward declare
class Son: public Base {
public:
    Son(Daughter* d);
};

// son.cpp
#include "son.h"
#include "daughter.h"
Son::Son(Daughter* d) : Base(*d) {}

// daughter.h
#include "base.h" // include because you need the definition for inheritance
class Son;        // forward declare needed
class Daughter: public Base {
public:
    Daughter(Son* s);
};

// daughter.cpp
#include "daughter.h"
#include "son.h"
Daughter::Daughter(Son* s) : Base(*s) {}