Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用嵌入的私有类重写Qt类_C++_Qt - Fatal编程技术网

C++ 用嵌入的私有类重写Qt类

C++ 用嵌入的私有类重写Qt类,c++,qt,C++,Qt,在许多情况下,我希望重写Qt类以扩展或修改其行为。但几乎所有Qt类都使用内部私有类,例如QNetworkDiskCachePrivate内部的QNetworkDiskCache。我知道这种方法有很多优点。但是私有类有一个巨大的问题:它使得重写类变得更加困难。对于其他C++类库,源代码通常是重写类方法,从父类中的实现中复制代码,并在这里和那里进行小修改,以实现我想要的行为。但是,在Qt中,私有类不导出,并且对派生类不可见。由于Qt类通过“d”成员维护私有类中的关键内部数据,私有内部类的不可见性使得

在许多情况下,我希望重写Qt类以扩展或修改其行为。但几乎所有Qt类都使用内部私有类,例如QNetworkDiskCachePrivate内部的QNetworkDiskCache。我知道这种方法有很多优点。但是私有类有一个巨大的问题:它使得重写类变得更加困难。对于其他C++类库,源代码通常是重写类方法,从父类中的实现中复制代码,并在这里和那里进行小修改,以实现我想要的行为。但是,在Qt中,私有类不导出,并且对派生类不可见。由于Qt类通过“d”成员维护私有类中的关键内部数据,私有内部类的不可见性使得行为扩展的可能性非常有限。您只能使用少数公开的公共方法

我尝试提取类的整个源文件,并重命名类名和文件名。但是Qt类库是如此的相互交织,以至于在大多数情况下从中提取一个类也是非常混乱的


我错过什么了吗?或者Qt类在可扩展性方面真的很糟糕?

你的方法是错误的,糟糕的!为了扩展Qt,以及更多的C++,代码不必复制源代码,并在需要的地方修改它。您应该(必须)使用扩展OOP(面向对象编程)范式。在C++中,你应该写一些类似的东西:

#include <iostream>

using namespace std;

class A
{
public:
    A(){x=1;}
    void writeName(){cout << "my name is A";}
    void writeNumber(){cout << "my number is " << x << endl;}
private:
    int x;
};

class B : public A
{
public:
    B(){}
    void writeName(){cout << "my name is B and i'm better then A" << endl;}
};

int main()
{
   B *b= new B();
   b->writeName();
   b->writeNumber();
   return 0;
}

//output:
my name is B and i'm better then A
my number is 1
#包括
使用名称空间std;
甲级
{
公众:
A(){x=1;}

void writeName(){coutQt类在可扩展性方面优于大多数类;它们通常有钩子来改变它们的行为,而无需复制和粘贴整个方法。尽管如此,如果普遍接受的扩展方法不起作用,是的,Qt类更难破解。这可能是一件好事,因为复制粘贴和区分基类实现意味着派生类不会得到基类实现中的任何改进或错误修复


如果你想这样做,你需要说服你的构建系统允许你包含私有头,然后引用你新实现中的私有类。注意Qt文档中的免责声明;当你这样做的时候,你会随着每一个新版本的Qt发布而面临崩溃(Qt只保证公共API,而您弄乱了它的内部).Qt的公共API可读性和文档性都非常好;内部代码可能非常隐秘,因此您真的非常想确保无法使用公共API完成您想要的任务。如果您仍然决心使用私有类的东西,。

不是所有的Qt类都应该可以修改。我想说,90%的时间里,Qt都在做同样的事情在可扩展性和细节隐藏方面是“正确的”事情。你确定你采取了正确的方法来实现你想要的功能吗?你应该询问如何完成给定的任务,而不是发布你已经选择的方法。你可能想通过具体解释你想要做什么来让这更具体
QNetworkDiskCache
。这个问题更容易回答,答案可以让你了解如何处理类似的问题。讽刺的是,你只是做了你说他不应该做的事情:复制重写方法的实现。你的B::writeName()实现与a::writeName()共享了相当大比例的代码。可能这只是一个示例。;)我不认为这样的东西真的有用。我知道应该扩展C++类的正确方法。假设基类设计得很好,没有bug。但是在某些情况下,你确实必须把基类的详细代码切成一个错误,或者修改一个小的行为。这项任务非常困难。你的方法在Qt中使用的私有实现的情况下不起作用。这是唯一有效的方法:你不必使用他们的私有数据。如果你依赖它,你会在Qt版本更改上遇到一些大麻烦。而在这种方法中,我建议即使Qt巨魔改变你的代码所能做的任何事情仍然有效,这是因为它们提供了ABI兼容性:不管怎样,这只是OOP编程。我从未听说过有人将基类代码复制到派生类中。是的。从父类复制并粘贴代码是最后的选择。但当没有其他选项时,至少它足以作为一种变通方法。在现实世界中,并非所有类都是这样每一个新版本都进行了彻底的修改。即使修改了,在下一个版本中再次应用相同的补丁通常也不会太麻烦。我用MFC做了很多这样的修复,多次节省了我的时间。但是使用QT,这样做真的很痛苦。