我得到了这个
#include <vector>
using namespace std;
class A{
protected:
int test;
public:
void test(){}
};
class B : public class A{
public:
void test2(){}
};
int main(){
vector <A> new_vector;
A a1;
new_vector.push_back(a1);
B b1;
new_vector.push_back(b1);
new_vector[0].test();
//THE PROBLEM IS HOW DO I DO THIS:
new_vector[1].test2();
}
逻辑上是可能的,但它给我一个错误,我是如何以正确的方式做到的?
在python中我总是以一种非常简单的方式做这样的事情,在c ++中是可能的吗?
答案 0 :(得分:1)
您的问题是该向量仅包含A
对象的空间,无法在其中放置B
。
对于多态,您需要指针,引用或智能指针。为了帮助终身管理,建议采用后者。
std::vector<std::unique_ptr<A>> new_vector;
new_vector.emplace_back(new A());
new_vector.emplace_back(new B());
然后,您可以对元素使用dynamic_cast
来发现是否确实存在B
和B
个特定成员。
但是,使用虚拟成员函数进行多态行为比dynamic_cast
更有效。
答案 1 :(得分:0)
你可以像python一样做到这一点,不是将对象直接存储到向量中,而是使用对实际对象本身的指针/引用。
#include <memory>
typedef std::vector<std::unique_ptr<A>> AVector;
在这种情况下允许多态,你可以将指针推送到从A派生的任何东西。
如果你试图尝试,你试图将圆钉钉入方孔。 std :: vector实际上实际上是一个简单的代码包装器,它分配了一大块内存成员* sizeof(T)。
“unique_ptr”是指针的C ++ 11容器,它知道在它消失时删除它。如果您没有C ++ 11 / C ++ 0x支持,您可以使用指针或创建自己的“自动”指针包装。
// Old-style pointer
typedef std::vector<A*> AVector;
AVector avec;
avec.push_back(new A);
avec.push_back(new B);
avec.push_back(new A);
avec.push_back(new B);
// now it's your responsibility to 'delete' these allocations when you remove them.
void discardAvec(size_t position) {
A* ptr = avec[position];
delete ptr;
avec.erase(avec.begin() + position);
}
查看at ideone.com下面的直播的实时演示:
#include <iostream>
#include <memory>
#include <vector>
typedef std::vector<class A*> AVector;
class A
{
protected: // so B can access it.
int m_i;
public:
A(int i_) : m_i(i_)
{
std::cout << "CTor'd A(i) " << (void*)this
<< " with " << m_i << std::endl;
}
A(int i_, bool) : m_i(i_)
{
std::cout << "CTor'd A(i, b) " << (void*)this
<< " with " << m_i << std::endl;
}
virtual ~A()
{
std::cout << "DTor'd A " << (void*)this << " with " << m_i << std::endl;
}
};
class B : public A
{
int m_j;
public:
B(int i_, int j_) : A(i_, true), m_j(j_)
{
std::cout << "CTor'd B(i, j) " << (void*)this
<< " with " << m_i << ", " << m_j << std::endl;
}
virtual ~B()
{
std::cout << "DTor'd B " << (void*)this
<< " with " << m_i << ", " << m_j << std::endl;
}
};
int main()
{
AVector avec;
std::cout << "create A(1)" << std::endl;
avec.push_back(new A(1)); // allocated an "A" on the heap.
std::cout << "create B(2, 1)" << std::endl;
avec.push_back(new B(2, 1)); // allocated a "B" on the heap.
std::cout << "create B(2, 2)" << std::endl;
avec.push_back(new B(2, 2));
std::cout << "create A(3) " << std::endl;
avec.push_back(new A(3));
std::cout << "populated avec" << std::endl;
A* ptr = avec[2]; // take the pointer of what is actually a B
avec.erase(avec.begin() + 2); // remove it from the vector.
std::cout << "removed entry 2 from the vector" << std::endl;
// 'ptr' is still valid because it's an allocation, and C++ doesn't
// garbage collect heap allocations. We have to 'delete' it ourselves.
// Also note that because A and B have virtual destructors,
// you will see both of them called.
delete ptr;
// Now watch what DOESN'T happen as we exit.
// everything we CTOR'd that doesn't get DTORd is a leak.
return 0;
}