C++、虚继承、奇怪的抽象类+克隆问题

标签 c++ inheritance virtual abstract-class clone

抱歉,源代码量较大。有三个抽象类P、L、PL。第三类 PL 使用虚拟继承从类 P 和 L 派生:

template <typename T>  //Abstract class
class P
{

    public:
            virtual ~P() = 0;
    virtual P <T> *clone() const  = 0;
};

template <typename T>
P<T>::~P() {}

template <typename T>
P<T> * P <T>:: clone() const { return new P <T> ( *this ); }

template <typename T>  //Abstract class
class L
{
    public:
            virtual ~L() = 0;
    virtual L <T> *clone() const = 0;
};

template <typename T>
L<T>::~L() {}

template <typename T>
L<T> *L <T> ::clone() const { return new L <T> ( *this );}

template <typename T>
class PL: virtual public P <T>, virtual public L <T>  //Abstract class
{
    public:
            PL() : P <T>(), L<T>() {}
    virtual ~PL() = 0;
    virtual PL <T> *clone() const  = 0;
};

template <typename T>
PL<T>::~PL() {}

template <typename T>
PL<T> * PL <T> :: clone() const { return new PL <T> ( *this );}

每个类都有自己的克隆方法实现。

接下来的两个类 PA、PC 是使用虚拟继承从类 P 派生的:

template <typename T>
class PC : virtual public P <T>
{
    public:
            PC() : P <T> () {}
            virtual ~PC() {}
            virtual PC <T> *clone() const {return new PC <T> ( *this );}
};

template <typename T>
class PA : virtual public P <T>
{
    public:
            PA() : P <T> () {}
            virtual ~PA() {}
            virtual PA <T> *clone() const {return new PA <T> ( *this );}
};

最后两个类 PCL 和 PAL 是使用 PC 和 PL 、 PA 和 PL 的虚拟继承派生的。

template <typename T>
class PCL : public PC <T>, public PL <T>
{
    public:
            PCL() : P <T> (), PC <T> (), PL <T> ()  {}
            virtual ~PCL() {}
            virtual PCL <T> *clone() const {return new PCL <T> ( *this );}
};

template <typename T>
class PAL : public PA <T>, public PL <T>
{
    public:
            PAL() : P <T> (), PA <T> (), PL <T> () {}
            virtual ~PAL() {}
            virtual PAL <T> *clone() const {return new PAL <T> ( *this );}

};

类依赖关系图:

.......... P .... L.....
........../|\..../......
........./.|.\../.......
......../..|..\/........
.......PC..PA..PL.......
.......|...|.../|.......
.......|...|../.|.......
.......|...PAL..|.......
.......|........|.......
.......PCL_____/........  

请不要讨论这个提案 :-)))。我有以下 3 个问题:

1) 这个类依赖是否用 C++ 正确重写了(首先是“虚拟”的位置)?

2)我不确定哪里出了问题,请看代码:

int main(int argc, _TCHAR* argv[])
{
PCL <double> * pcl = new PCL <double>(); //Object of abstract class not allowed
PAL <double> * pal = new PAL <double>(); //Object of abstract class not allowed
PL <double> *pl1 = pcl->clone(); //Polymorphism
PL <double> *pl2 = pal->clone(); //Polymorphism
return 0;
} 

无法创建 PAL/PCL 类的新对象,这两个类都标记为抽象类。但它们并不抽象。问题出在哪里?

3) 是否可以将多态与 clone() 方法一起使用?请看上面的代码...

感谢您的帮助...


更新问题

我更正了代码。但是使用VS 2010编译器出现如下错误:

template <typename T>  //Abstract class
class P
{
    public:
    virtual ~P() = 0;
    virtual P <T> *clone() const  = 0;
};

template <typename T>
P<T>::~P() {}

template <typename T>
P<T> * P <T>:: clone() const { return new P <T> ( *this ); }


template <typename T>  //Abstract class
class L
{
    public:
    virtual ~L() = 0;
    virtual L <T> *clone() const = 0;
};

template <typename T>
L<T>::~L() {}

template <typename T>
L<T> *L <T> ::clone() const { return new L <T> ( *this );}


template <typename T>
class PL: virtual public P <T>, virtual public L <T>  //Abstract class
{
    public:
            PL() : P <T>(), L<T>() {}
    virtual ~PL() = 0;
    virtual PL <T> *clone() const  = 0; 
};

template <typename T>
PL<T>::~PL() {}

template <typename T>
PL<T> * PL <T> :: clone() const { return new PL <T> ( *this );}


template <typename T>
class PC : virtual public P <T>
{
    protected:
            T pc;
    public:
            PC() : P <T> () {}
    virtual ~PC() {}
            virtual PC <T> *clone() const {return new PC <T> ( *this );}
};

template <typename T>
class PA : virtual public P <T>
{
    public:
            PA() : P <T> () {}
    virtual ~PA() {}
            virtual PA <T> *clone() const {return new PA <T> ( *this );}
};

template <typename T>
class PCL : public PC <T>, public PL <T>
{
public:
            PCL() : P <T> (), PC <T> (), PL <T> () {}
            virtual ~PCL() {}
            virtual PCL <T> *clone() const {return new PCL <T> ( *this   );}
}; //Error using VS 2010: Error 1   error C2250: 'PCL<T>' : ambiguous inheritance of 'PC<T> *P<T>::clone(void) const'


template <typename T>
class PAL : public PA <T>, public PL <T>
{
public:
            PAL() : P <T> (), PA <T> (), PL <T> ()  {}
            virtual ~PAL() {}
            virtual PAL <T> *clone() const {return new PAL <T> ( *this );}
}; //Error VS 2010: Error   1   error C2250: 'PAL<T>' : ambiguous inheritance of 'PA<T> *P<T>::clone(void) const'


int main(int argc, char* argv[])
{
PCL <double> * pcl = new PCL <double>();
PAL <double> * pal = new PAL <double>();
PL <double> *pl1 = pcl->clone();
PL <double> *pl2 = pal->clone();
return 0;
}

也许我忽略了什么...但是 g++ 编译这段代码没问题。

最佳答案

代码中的一些小错误:

  • 正确获取基础初始化器:PAL() : PC <T>(), PL <T>() {} P<T> 没有初始化,这不是直接基础;但是[抱歉,那是错误的——由于虚拟继承,您确实必须调用虚拟基础构造函数。]您必须说圆括号。

  • 声明没有定义的纯虚函数:virtual L <T> *clone() const = 0;

  • 仔细检查您想要 PLP 虚拟继承但不是虚拟的 L (但这很好)。

  • 仔细检查您所有的 clone() s 具有相同的常量。

  • 如果抽象基类中已经有一个纯虚函数,则不应将析构函数设为纯。相反,说 virtual ~T() { } .否则,您仍应提供纯虚拟析构函数的定义(因为析构函数始终需要可调用):virtual T::~T() { }

关于C++、虚继承、奇怪的抽象类+克隆问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6927405/

相关文章:

c++ - 如何在解决方案中构建多个项目之前执行流程

c++ - 如何使用cmake编译依赖项?

java - 当基类有带参数的构造函数时,为什么我不能创建无参数的子类构造函数?

java - 如何在两个不同的 Swing 窗口之间共享方法?

c++ - 返回不同类型的派生虚函数——指针

c# - C#中虚方法的问题

c++ - 在 UMFPACK 中,我们需要多久进行一次符号和数值分解?

c++ - 提升图形库 : possible to combine Bundled Properties with Interior Properties?

java - 我的继承代码正确吗?

c++ - 匿名类上的虚拟表