我有两个类层次结构:A
s和B
s。 A
的虚方法返回B
,B
的虚方法返回A
。
A.H
#pragma once
class B;
struct A
{
virtual B* f() = 0;
};
A1.h
#pragma once
#include "A.h"
#include "B1.h"
struct A1 : public A
{
B1* f() override;
};
B.h
#pragma once
class A;
struct B
{
virtual A* g() = 0;
};
B1.h
#pragma once
#include "B.h"
#include "A1.h"
struct B1 : public B
{
A1* g() override;
};
在VS2015
中无法编译错误overriding virtual function return type differs and is not covariant from A
使用课程转发声明
class A1 : public A;
它应该有用。但是C ++不支持这样的类前向声明。如何解决?
答案 0 :(得分:1)
在处理循环引用时,请在适当的地方使用前向声明而不是#include
语句。
此外,头文件本身应该有防护,以避免在多次#include
多次时多次声明其内容。警卫本身可以使用#ifndef
/ #define
对或#pragma once
,具体取决于您的编译器。
A.H
#ifndef A_H
#define A_H
struct B;
struct A
{
virtual B* f() = 0;
};
#endif
或者:
#pragma once
struct B;
struct A
{
virtual B* f() = 0;
};
A1.h:
#ifndef A1_H
#define A1_H
#include "A.h"
struct B1;
struct A1 : public A
{
B1* f() override;
};
#endif
或者:
#pragma once
#include "A.h"
struct B1;
struct A1 : public A
{
B1* f() override;
};
A2.h
#ifndef A2_H
#define A2_H
#include "A.h"
struct B2;
struct A2 : public A
{
B2* f() override;
};
#endif
或者:
#pragma once
#include "A.h"
struct B2;
struct A2 : public A
{
B2* f() override;
};
B.h
#ifndef B_H
#define B_H
struct A;
struct B
{
virtual A* g() = 0;
};
#endif
或者:
#pragma once
struct A;
struct B
{
virtual A* g() = 0;
};
B1.h
#ifndef B1_H
#define B1_H
#include "B.h"
struct A1;
struct B1 : public B
{
A1* g() override;
};
#endif
或者:
#pragma once
#include "B.h"
struct A1;
struct B1 : public B
{
A1* g() override;
};
B2.h
#ifndef B2_H
#define B2_H
#include "B.h"
struct A2;
struct B2
{
A2* g() override;
};
#endif
或者
#pragma once
#include "B.h"
struct A2;
struct B2
{
A2* g() override;
};
要满足前向声明的类的#include
语句应该在方法实现源文件中使用,而不是在它们的声明头文件中使用:
A1.cpp:
#include "A1.h"
#include "B1.h" // <--
B1* A1::f()
{
return new B1; // or wherever the B1 object comes from...
}
A2.h
#include "A2.h"
#include "B2.h" // <--
B2* A2::f()
{
return new B2; // or wherever the B2 object comes from...
}
B1.cpp
#include "B1.h"
#include "A1.h" // <--
A1* B1::g()
{
return new A1; // or wherever the A1 object comes from...
}
B2.cpp
#include "B2.h"
#include "A2.h" // <--
A2* B2::g()
{
return new A2; // or wherever the A2 object comes from...
}
话虽这么说,前面声明结构是处理循环引用的唯一方法。但由于您无法转发声明层次结构,因此我认为如果不重新考虑您的设计,您的问题就无法解决。如果这不是一个选项,您将不得不停止使用协变返回值。
A.H
#pragma once
struct B;
struct A
{
virtual B* f() = 0;
};
A1.h:
#pragma once
#include "A.h"
struct A1 : public A
{
B* f() override;
};
A2.h
#pragma once
#include "A.h"
struct A2 : public A
{
B* f() override;
};
B.h
#pragma once
struct A;
struct B
{
virtual A* g() = 0;
};
B1.h
#pragma once
#include "B.h"
struct B1 : public B
{
A* g() override;
};
B2.h
#pragma once
#include "B.h"
struct B2
{
A* g() override;
};
A1.cpp:
#include "A1.h"
#include "B1.h" // <--
B* A1::f()
{
return new B1; // or wherever the B1 object comes from...
}
A2.h
#include "A2.h"
#include "B2.h" // <--
B* A2::f()
{
return new B2; // or wherever the B2 object comes from...
}
B1.cpp
#include "B1.h"
#include "A1.h" // <--
A* B1::g()
{
return new A1; // or wherever the A1 object comes from...
}
B2.cpp
#include "B2.h"
#include "A2.h" // <--
A* B2::g()
{
return new A2; // or wherever the A2 object comes from...
}
这只是意味着在调用f()
和g()
时,无论您在哪里依赖协方差,都必须使用类型转换。