C+上的部分类定义+;? 谁知道C++上有可能有部分类定义?< /P>
比如: 文件1.h: class Test { public: int test1(); }; 课堂测试{ 公众: int test1(); }; 文件2.h: class Test { public: int test2(); }; 课堂测试{ 公众: int test2(); }; 对我来说,它对于定义多平台类非常有用,这些类之间具有与平台无关的公共函数,因为继承是一种对多平台类没有用处的代价 我的意思是,在运行时,您永远不会有两个多平台专门化实例,只有在编译时。继承可能有助于满足您的公共接口需求,但在此之后,它不会在运行时添加任何有用的内容,只会增加成本 此外,您还必须使用丑陋的ifdef来使用该类,因为您无法从抽象类生成实例: class genericTest { public: int genericMethod(); }; 类泛型测试{ 公众: int genericMethod(); }; 那么让我们假设对于win32: class win32Test: public genericTest { public: int win32Method(); }; 类win32Test:公共泛型测试{ 公众: int win32Method(); }; 也许: class macTest: public genericTest { public: int macMethod(); }; macTest类:公共泛型测试{ 公众: int macMethod(); }; 假设win32Method()和macMethod()都调用genericMethod(),您必须像这样使用该类: #ifdef _WIN32 genericTest *test = new win32Test(); #elif MAC genericTest *test = new macTest(); #endif test->genericMethod(); #ifdef_WIN32 genericTest*测试=新的win32Test(); #艾利夫麦克 genericTest*测试=新的macTest(); #恩迪夫 测试->通用方法(); 现在想一想,继承只在为它们提供一个依赖于特定平台的genericMethod()时才有用,但是您需要为此调用两个构造函数。此外,代码中还散布着丑陋的ifdef 这就是为什么我在寻找部分课程。我可以在编译时定义特定的依赖于平台的部分结束,当然,在这个愚蠢的示例中,我仍然需要一个丑陋的“ifdef inside genericMethod(),但还有其他方法可以避免这种情况。尝试继承 具体地C+上的部分类定义+;? 谁知道C++上有可能有部分类定义?< /P>,c++,C++,比如: 文件1.h: class Test { public: int test1(); }; 课堂测试{ 公众: int test1(); }; 文件2.h: class Test { public: int test2(); }; 课堂测试{ 公众: int test2(); }; 对我来说,它对于定义多平台类非常有用,这些类之间具有与平台无关的公共函数,因为继承是一种对多平台类没有用处的代价 我的意思是,在运行时,您永远不会有两个多平台专门化
class AllPlatforms {
public:
int common();
};
然后
class PlatformA : public AllPlatforms {
public:
int specific();
};
<>这是不可能的C++,它会给你一个错误,关于重新定义已经定义的类。如果您想共享行为,请考虑继承。< /p> 如所写,不可能。 您可能需要查看名称空间。可以将函数添加到另一个文件的命名空间中。类的问题是每个.cpp都需要查看类的完整布局。否
但是,您可能需要查找一种称为“策略类”的技术。基本上,您可以创建微类(它们本身没有用处),然后在以后的某个时候将它们粘在一起。两次声明类主体可能会产生类型重新定义错误。如果你在找工作的话。我建议使用杰米来隐藏平台特定的细节。< /P> < P>要么使用继承,如使用的,要么用IFIFF来在不同的平台上编译不同的部分。 < P>因为头只是文本插入,其中一个可以省略“类测试{”和“}”,并且包含在另一个中间。 我在生产代码中看到了这一点,尽管不是Delphi,不是C++。这让我特别恼火,因为它破坏了IDE的代码导航功能 对我来说,它对于定义多平台类似乎非常有用,这些类之间具有与平台无关的公共函数 除了开发人员几十年来一直在这样做,没有这个“特性” 我相信创建partial是因为微软几十年来一直有一个坏习惯,即生成代码并将其交给开发人员进行开发和维护 生成的代码通常是维护的噩梦。当您需要升级MFC版本时,整个MFC生成的框架有哪些习惯?或者,在升级Visual Studio时,如何将所有代码移植到*.designer.cs文件中 大多数其他平台更依赖于生成用户/开发人员可以修改的配置文件。它们的词汇量比较有限,不容易与无关的代码混合。如果认为有必要,配置文件甚至可以作为资源文件插入到二进制文件中
我从未见过在继承或配置资源文件无法更好地工作的地方使用“partial”。使用模板专门化和partial专门化可以得到类似于partial类的东西。在投入太多时间之前,请检查编译器对这些的支持。MSC++6.0等较旧的编译器不支持部分专门化。或者您可以尝试PIMPL 通用头文件:
class Test
{
public:
...
void common();
...
private:
class TestImpl;
TestImpl* m_customImpl;
};
然后创建cpp文件,执行特定于平台的自定义实现。如何:
class WindowsFuncs { public: int f(); int winf(); };
class MacFuncs { public: int f(); int macf(); }
class Funcs
#ifdef Windows
: public WindowsFuncs
#else
: public MacFuncs
#endif
{
public:
Funcs();
int g();
};
现在的代码>函数> /COD>是编译时已知的类,所以抽象基类或任何东西都不造成开销。
< P>不能部分定义C++中的类。#include will work as that is preprocessor stuff.
class Foo
{
#include "FooFile_Private.h"
}
////////
FooFile_Private.h:
private:
void DoSg();
这里有一种方法可以获得您想要的“多态性,其中只有一个子类”效果,而不需要额外的开销,并且只需要最少的#定义或代码重复。这称为模拟动态绑定:
template <typename T>
class genericTest {
public:
void genericMethod() {
// do some generic things
std::cout << "Could be any platform, I don't know" << std::endl;
// base class can call a method in the child with static_cast
(static_cast<T*>(this))->doClassDependentThing();
}
};
#ifdef _WIN32
typedef Win32Test Test;
#elif MAC
typedef MacTest Test;
#endif
模板
类泛型测试{
公众:
void genericMethod(){
//做一些普通的事情
标准::cout
这在C++中是不可能的,它会给你一个关于重新定义已经定义的错误。
类。如果您想共享行为,请考虑继承。
我同意这一点。分部类是一种奇怪的构造,这使得以后很难维护。很难找到每个成员声明的分部类,很难避免重新定义甚至重新实现特性
如果要扩展std::vector,则必须从它继承。这是因为以下几个原因。首先,更改类的责任和(正确地)其类不变量。其次,从安全角度来看,应该避免这样做。
考虑一个处理用户身份验证的类…
partial class UserAuthentication {
private string user;
private string password;
public bool signon(string usr, string pwd);
}
partial class UserAuthentication {
private string getPassword() { return password; }
}
还有很多其他原因
class MacTest : public genericTest<MacTest> {
public:
void macMethod() {
// mac-specific stuff:
std::cout << "I'm in MacOS" << std::endl;
// we can call a method in the base class
genericMethod();
// more mac-specific stuff...
}
void doClassDependentThing() {
std::cout << "Yep, definitely in MacOS" << std::endl;
}
};
#ifdef _WIN32
typedef genericTest<Win32Test> BaseTest;
#elif MAC
typedef genericTest<MacTest> BaseTest;
#endif
partial class UserAuthentication {
private string user;
private string password;
public bool signon(string usr, string pwd);
}
partial class UserAuthentication {
private string getPassword() { return password; }
}
#ifndef TEST_H
#define TEST_H
class Test
{
public:
Test(void);
virtual ~Test(void);
#include "Test_Partial_Win32.h"
#include "Test_Partial_OSX.h"
};
#endif // !TEST_H
// This file should be included in Test.h only.
#ifdef MAC
public:
int macMethod();
#endif // MAC
// This file should be included in Test.h only.
#ifdef _WIN32
public:
int win32Method();
#endif // _WIN32
// Implement common member function of class Test in this file.
#include "stdafx.h"
#include "Test.h"
Test::Test(void)
{
}
Test::~Test(void)
{
}
// Implement OSX platform specific function of class Test in this file.
#include "stdafx.h"
#include "Test.h"
#ifdef MAC
int Test::macMethod()
{
return 0;
}
#endif // MAC
// Implement WIN32 platform specific function of class Test in this file.
#include "stdafx.h"
#include "Test.h"
#ifdef _WIN32
int Test::win32Method()
{
return 0;
}
#endif // _WIN32
template <typename TResource, typename TParams, typename TKey>
class IResource
{
public:
virtual TKey GetKey() const = 0;
protected:
static shared_ptr<TResource> Create(const TParams& params)
{
return ResourceManager::GetInstance().Load(params);
}
virtual Status Initialize(const TParams& params, const TKey key, shared_ptr<Viewer> pViewer) = 0;
};
template <typename TResource, typename TParams, typename TKey>
class TResourceManager
{
sptr<TResource> Load(const TParams& params) { ... }
};
class Texture2D : public IResource<Texture2D , Params::Texture2D , Key::Texture2D >
{
typedef TResourceManager<Texture2D , Params::Texture2D , Key::Texture2D > ResourceManager;
friend class ResourceManager;
public:
virtual Key::Texture2D GetKey() const override final;
void GetWidth() const;
private:
virtual Status Initialize(const Params::Texture2D & params, const Key::Texture2D key, shared_ptr<Texture2D > pTexture) override final;
struct Impl;
unique_ptr<Impl> m;
};
// D3DTexture2DImpl.h
#include "Texture2D.h"
struct Texture2D::Impl
{
/* insert D3D-specific stuff here */
};
// OGLTexture2DImpl.h
#include "Texture2D.h"
struct Texture2D::Impl
{
/* insert OGL-specific stuff here */
};
// Texture2D.cpp
#include "Texture2D.h"
#ifdef USING_D3D
#include "D3DTexture2DImpl.h"
#else
#include "OGLTexture2DImpl.h"
#endif
Key::Texture2D Texture2D::GetKey() const
{
return m->key;
}
// etc...
class MyClass
{
#include <MyClass_Part1.hpp>
#include <MyClass_Part2.hpp>
#include <MyClass_Part3.hpp>
};