Ell*_*Ell 5 c++ inheritance cross-platform class
我正在绞尽脑汁试图找出如何编写跨平台类,同时避免虚拟函数的成本和平台特定版本的类中的任何丑陋.这是我尝试过的.
PlatformIndependantClass.hpp
class PlatformIndependantClass {
public:
PlatformIndependantClass();
std::string GetPlatformName();
private:
PlatformIndependantClass* mImplementation;
};
Run Code Online (Sandbox Code Playgroud)
LinuxClass.hpp
#include "PlatformIndependantClass.hpp"
class LinuxClass : public PlatformIndependantClass{
public:
std::string GetPlatformName();
};
Run Code Online (Sandbox Code Playgroud)
WindowsClass.hpp
#include "PlatformIndependantClass.hpp"
class WindowsClass : public PlatformIndependantClass {
public:
std::string GetPlatformName();
};
Run Code Online (Sandbox Code Playgroud)
PlatformIndependantClass.cpp
#include "PlatformIndependantClass.hpp"
#include "LinuxClass.hpp"
#include "WindowsClass.hpp"
PlatformIndependantClass::PlatformIndependantClass() {
#ifdef TARGET_LINUX
mImplementation = new LinuxClass();
#endif
#ifdef TARGET_WINDOWS
mImplementation = new WindowsClass();
#endif
}
std::string PlatformIndependantClass::GetPlatformName() {
return mImplementation->GetPlatformName();
}
Run Code Online (Sandbox Code Playgroud)
LinuxClass.cpp
#include "LinuxClass.hpp"
std::string LinuxClass::GetPlatformName() {
return std::string("This was compiled on linux!");
}
Run Code Online (Sandbox Code Playgroud)
WindowsClass.cpp
#include "WindowsClass.hpp"
std::string WindowsClass::GetPlatformName() {
return std::string("This was compiled on windows!");
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <iostream>
#include "PlatformIndependantClass.hpp"
using namespace std;
int main()
{
PlatformIndependantClass* cl = new PlatformIndependantClass();
cout << "Hello world!" << endl;
cout << "Operating system name is: " << cl->GetPlatformName() << endl;
cout << "Bye!" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,这编译得很好但我得到了一个分段错误.我相信这是因为平台特定的类继承自PlatformIndependantClass,它在构造时创建了特定于平台的类的实例,因此我获得了无限的递归.每次我尝试,我都会非常困惑!
如何才能正确实现这样的设计?或者这只是一个可怕的想法.我一直试图找出如何编写跨平台类,但我只是得到了一些关于跨平台库的结果,任何帮助都将被感激地接受:)
从最后开始,是的,真的是一个可怕的想法,大多数想法都以"我想避免虚拟功能的成本"开头.
至于你为什么会遇到分段错误(特别是堆栈溢出),这是因为你没有使用虚函数,而是使用静态链接.编译器不知道mImplementation除了a之外什么都不是PlatformIndependantClass,所以当你试图调用时,你return mImplementation->GetPlatformName()一遍又一遍地调用同一个函数.
你所取得的成就叫做阴影,你正在使用编译时功能解析.编译器将调用您正在调用它的变量的实际类型的GetPlatformName函数,因为没有虚拟表来覆盖指向实际函数的指针.由于是,永远是.mImplementationPlatformIndependantClassmImplementation->GetPlatformNamePlatformIndependantClass::GetPlatformName
编辑:当然,我想到了为什么你需要同时创建引擎的Windows和Linux副本的问题.你永远不会同时使用它们,对吧?
那么为什么不只是有两个不同的库,每个系统一个,并从您的makefile链接正确的库.你将获得最好的世界!
我认为你想要完成的事情可以更轻松地完成......
Object.h:
#include <normal includes>
#if WINDOWS
#include <windows includes>
#endif
#if LINUX
#include <linux includes>
#endif
class Object
{
private:
#if WINDOWS
//Windows Specific Fields...
#endif
#if LINUX
//Linux Specific Fields...
#endif
public:
//Function that performs platform specific functionality
void DoPlatformSpecificStuff();
//Nothing platform specific here
void DoStuff();
};
Run Code Online (Sandbox Code Playgroud)
Object.cpp
#include "Object.h"
void Object::DoStuff() { ... }
Run Code Online (Sandbox Code Playgroud)
ObjectWin32.cpp
#if WINDOWS
#include "Object.h"
void Object::DoPlatformSpecificStuff()
{
//Windows specific stuff...
}
#endif
Run Code Online (Sandbox Code Playgroud)
ObjectLinux.cpp
#if LINUX
#include "Object.h"
void Object::DoPlatformSpecificStuff()
{
//Linux specific stuff...
}
#endif
Run Code Online (Sandbox Code Playgroud)
等等.我认为这可以通过更简单的方式完成您的尝试.此外,不需要虚拟功能.