C ++,虚拟继承,奇怪的抽象类+克隆问题 [英] C++, virtual inheritance, strange abstract class + clone problem

查看:135
本文介绍了C ++,虚拟继承,奇怪的抽象类+克隆问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于较大量的源代码,对不起。有三个抽象类P,L,PL。第三类PL是使用虚拟继承从类P和L派生的:

Sorry for the larger amount of the source code. There three abstract classes P, L, PL. The third class PL is derived from classes P and L using the virtual inheritance:

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 );}



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

Every class has its own implementation of the clone method.

两个类PA,PC是使用虚拟继承派生自P类:

Two next classes PA, PC are derived from class P using the virtual inheritance:

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的虚拟继承。

The last two classes PCL and PAL are dirived using the virtual inheritance from PC and PL , PA and 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个问题:

Please, do not discuss this proposal :-))). I have the following 3 questions:

1)这个类依赖是否在C ++中正确地重写了(首先是虚拟的放置)?

1) Was this class dependency rewritten in C++ correctly (first of all the placemement of "virtual")?

2)我不知道是什么问题,请看代码:

2) I am not sure what is wrong, see the code, please:

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类的新对象被标记为抽象。但他们不是抽象的。问题在哪里?

It is not possible to create new objects of PAL / PCL classes, both classes are marked as abstract. But they are not abstract. Where is the problem?

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

3) Is it possible to use polymorphism together with clone() method? See the code above, please...

感谢您的帮助...

UPDATED QUESTION

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

I corrected the code. But the following error using VS 2010 compiler appear:

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 ++编译这段代码确定。 p>

Maybe i overlooked something... But g++ compiles this code OK.

推荐答案

这将为我编译使用VC10:

This compiles for me using VC10:

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>  //Abstract class
class L
{
public:
    virtual ~L() = 0;
    virtual L <T> *clone() const = 0;
};

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


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; // REMOVED!
};

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


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   );}
};


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 );}
};


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

注意,我不得不删除 PL< T> ; * PL T :: clone()以获得VC接受代码。问题是,如果你有一个 PL ,并且调用它的 clone()将静态地返回 L <* $ ,而不是 PL * ,即使动态类型是从 PL 派生的类。

Note that I had to remove PL <T> *PL <T>::clone() to get VC to accept the code. The problem with that is that, if you have a PL<T>, and call it's clone(), it will statically return an L<T>*, rather than a PL<T>*, even though the dynamic type is of a class derived from PL<T>.

这篇关于C ++,虚拟继承,奇怪的抽象类+克隆问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆