純粋な仮想基本クラスで明示的な関数を作成せずにコピーの構築を行うことはできませんか?
質問
私の目的はクラスのディープコピーを行うことですが、仮想クラスが問題を引き起こしています。
#include<iostream>
using namespace std;
class Vir//pure virtual class
{
public:
virtual void hi()=0;
};
class Handler:public Vir
{
public:
int i;
Handler() {}
Handler(int val):i(val) {}
void hi() {cout<<"Value of i="<<i<<endl;}
int getI() const {return i;}
void setI(int j) {i=j;}
};
class ControlPanel
{
public:
Vir *v;
ControlPanel(const ControlPanel& c)//copy constructor
{
v=new Handler;
v->setI(c.getI());
}
int getI()const {return v->getI();}
void initialize() {v=new Handler(10);}
void hi() {v->hi();}
ControlPanel() {}
~ControlPanel() {delete v;}
};
int main()
{
ControlPanel cc;
cc.initialize();
cc.hi();
ControlPanel bb(cc);//copying cc into bb
}
コンパイルエラーメッセージ:
test.cpp: In copy constructor ‘ControlPanel::ControlPanel(const ControlPanel&)’:
test.cpp:28: error: ‘class Vir’ has no member named ‘setI’
test.cpp: In member function ‘int ControlPanel::getI() const’:
test.cpp:30: error: ‘class Vir’ has no member named ‘getI’
Vir から継承し、独自のユニークなメンバー (float a; など) を持つハンドラー クラス (Handler1、Handler2 など) をさらにたくさん用意する予定です。またはダブルb;等)。したがって、すべての Handler クラスのすべてのゲッター関数とセッター関数を Vir クラスに保持することは意味がありません。メンバーは Handler クラスに固有であるため、getter メソッドと setter メソッドを Handler クラス内に保持したいと考えています。コンパイラがそれを許可していません。ヘルプ?
解決
もしかしたら何かが足りないかもしれませんが、仮想の方が良いのではないでしょうか? clone
メソッドオン Vir
?つまり、 ControlPanel
あなた自身の答えで概説されているコピーコンストラクター。これは、@Andrew Aylett が示唆していることと同じです。 彼の答え と duplicate
の代わりに使用されています clone
.
何かのようなもの
class Vir
{
public:
virtual Vir* clone() const = 0;
...
};
で実装されています Handler
することが
Handler* Handler::clone() const
{
return new Handler( *this );
}
共変の戻り値の型の使用に注意してください。 Handler::clone
を返すことが許可されています Handler*
ただではなく Vir*
そして依然として有効なオーバーライドである Vir::clone
.
これにより、 ControlPanel
コンストラクターを単純にコピーする
ControlPanel( const ControlPanel& c )
: v( c.v->clone() )
{
}
他のヒント
正しい値を返すことで新しいインスタンスを作成します(各派生クラスで)あなたの抽象クラスにduplicate()
機能を追加します。また、あなたがコピーし、正しいタイプからそうであればフィールドをコピーしていることを確認するために、どのチェックcopyFrom(Abs other)
機能を検討します。
一般的に、具体的なHandlerオブジェクトを検査することによって、その重複をやろうとすべきではない、それはそのオブジェクト上の仮想関数を切る重複を渡す必要があります。
Vir *v
に変更Handler *v;
とあなたのコードのコンパイルかどうかを参照してください。
あなたのクラスVir
がsetI()
とgetI()
メンバー関数を定義/宣言していません。
または
としてVir
を定義します
class Vir//pure virtual class
{
public:
virtual void hi()=0;
virtual int getI()const =0;
virtual void setI(int)=0;
};
あなたはサブクラスを経由してそれらにアクセスできるようにgetI
に仮想(純粋)としてsetI
とVir
を定義する必要があります。これを回避する方法はありません。
、私は自分の質問に答えますよ。希望は、この仮想クラスはバリケードかもしれC ++でディープコピーを行う方法の疑問を持っている誰にも助けになるでしょう。ホープ誰かが、これは重宝ます。
#include<iostream>
using namespace std;
class Vir//pure virtual class
{
public:
virtual void hi()=0;
virtual int getI() {std::cout << "Inside Base class" << std::endl;}
virtual void setI(int i) {cout<<"In base"<<endl;}
virtual int getX() {}
virtual void setX(int x) {}
};
class Model
{
public:
int x;
Model(const Model& mm) {x=mm.x;}
Model():x(555) {cout<<"Model constructor called"<<endl;}
int getX() {return x;}
void setX(int xx) {x=xx;}
};
class Handler:public Vir
{
public:
int i;
Model *m;
Handler() {m=new Model;cout<<"Handler constructor called"<<endl;}
Handler(const Handler& h)
{
std::cout << "Inside Handler @lineNumber:" << __LINE__ << std::endl;
i=h.i;
m=new Model(*h.m);
}
Handler(int val):i(val) {}
~Handler() {delete m;}
void hi() {cout<<"Value of i="<<i<<endl;}
int getI() {return i;}
void setI(int j) {i=j;}
int getX() {return m->getX();}
void setX(int xx) {m->setX(xx);}
};
class ControlPanel
{
public:
int abc;
Vir *v;
ControlPanel(const ControlPanel& c)//copy constructor
{
std::cout << "Inside ControlPanel @lineNumber:" << __LINE__ << std::endl;
v=new Handler((Handler&)*(c.v));
}
void initialize() {v=new Handler();v->setI(10);abc=222;}
void hi() {v->hi();}
ControlPanel() {}
~ControlPanel() {delete v;}
};
int main()
{
ControlPanel cc;
cc.initialize();
cc.hi();
cout << "(cc.v)->i::" << (cc.v)->getI() << endl;
cout<<"x value cc="<<(cc.v)->getX()<<endl;
ControlPanel bb(cc);//copying cc into bb
cout << "(bb.v)->i::" << (bb.v)->getI() << endl;
cout<<"x value bb="<<(bb.v)->getX()<<endl;
(cc.v)->setI(999);
(cc.v)->setX(888888888);
cout << "(cc.v)->i::" << (cc.v)->getI() << endl;
cout << "(bb.v)->i::" << (bb.v)->getI() << endl;
cout<<"x value cc="<<(cc.v)->getX()<<endl;
cout<<"x value bb="<<(bb.v)->getX()<<endl;
}//main
/*
Output:
Model constructor called
Handler constructor called
Value of i=10
(cc.v)->i::10
x value cc=555
Inside ControlPanel @lineNumber:52
Inside Handler @lineNumber:32
(bb.v)->i::10
x value bb=555
(cc.v)->i::999
(bb.v)->i::10
x value cc=888888888
x value bb=555 */