在没有reinterpret_cast的情况下从前向声明的兄弟中构造父级

时间:2015-03-21 17:55:25

标签: c++ inheritance constructor siblings reinterpret-cast

我尝试使用给定兄弟对象的指针调用父构造函数:

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){};
};

呃 - 哦:(link to run

  

错误:没有匹配函数来调用&#39;女儿::女儿(基地&amp;)&#39;

     

注意:候选人是:

     

注意:女儿::女儿(const Base&amp;)

     

注意:来自&#39;女儿&#39;的参数1没有已知的转换。 to&#39; const Base&amp;&#39;

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

我已经能够解决&#39;它:

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

但这似乎是不好的做法 - 我认为我不应该reinterpret_cast出于某种无辜的意图 - 我们都知道Son a派生类Base

有没有更好的方法来解决这个问题?

NB: 虽然它可能来自糟糕的整体设计 - &#34; [我]不应该从兄弟姐妹中建立父母。&#34; - 请记住,我从一个更大的设计(更多的兄弟姐妹,每个更多的构造函数)减少到一个非常小的例子,其中这样做是必要的几个地方。

2 个答案:

答案 0 :(得分:1)

您的课程是循环依赖的。如果将定义移到两个类的定义后面,则可以修复&#34;不完整的类&#34;问题

请注意,定义必须只定义一次,或定义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(){
}

(但这并没有解决其他问题 - 设计很漂亮)

答案 1 :(得分:1)

您必须在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) {}