从没有 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) {}
我正在尝试调用 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
!
有没有更好的方法来处理这个问题?
注意: 虽然它可能确实来自糟糕的整体设计 - “[我] 不需要从兄弟姐妹那里构建一个 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) {}