スーパークラスへのポインターのベクトルがあり、そのベクトルにサブクラスのメンバーを追加すると、サブクラス関数を問題なく呼び出すことができますが、コードが現在のところ、サブクラスに固有の変数にアクセスできません。のB
ポインタからアクセスするにはどうすればよいvec
ですか?
#include <iostream>
#include <vector>
class Super {
public:
int A;
Super(int a) : A(a) {}
virtual void foo() = 0;
};
class Sub : public Super {
public:
int B;
Sub(int a, int b) : Super(a), B(b) {}
void foo() {
std::cout << "calling foo from Sub\n";
}
};
int main() {
std::vector<Super*> vec;
vec.push_back(new Sub(2, 3));
vec[0]->foo(); // No problem
std::cout << "A: " << vec[0]->A << std::endl; // No problem
std::cout << "B: " << vec[0]->B << std::endl; // Compile Error
}
dynamic_cast<Sub*>
(またはstatic_cast<Sub*>
、各ポインタがを指していることを保証できる場合でも)でそれを素朴に修正することはできますSub
が、…しないでください!これは仮想ディスパッチの教科書ケースです。
継承階層全体のインターフェイスvirtual void print(std::ostream&)
の一部であると、operator<<
その階層内の任意のタイプのオブジェクトで呼び出すことができるを追加します。そう、C ++ランタイム多型の魔法と機能があなたのためにすべてこれを行うオーバーライドしてみましょうmain
との違いについて知る必要はありませんA
か、B
それぞれが持っているか、どのようなメンバ変数、また図にどの種類のオブジェクトのあなたのポインタの各実際の点から。
また、メモリリークを回避するために、スマートポインタを格納する必要があります。
#include <iostream>
#include <vector>
#include <memory>
struct Super {
int A;
Super(int a) : A(a) {}
virtual void foo() = 0;
virtual void print(std::ostream& os) const
{
os << "A: " << A << '\n';
};
};
struct Sub : Super {
int B;
Sub(int a, int b) : Super(a), B(b) {}
void foo() { std::cout << "calling foo from Sub\n"; }
virtual void print(std::ostream& os) const
{
Super::print(os);
os << "B: " << B << '\n';
}
};
std::ostream& operator<<(std::ostream& os, const Super& obj)
{
obj.print(os);
return os;
}
int main()
{
std::vector<std::unique_ptr<Super>> vec;
vec.emplace_back(std::make_unique<Sub>(2, 3));
vec[0]->foo();
std::cout << *(vec[0]);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加