Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 访问基列表的子成员_C++_List_Class - Fatal编程技术网

C++ 访问基列表的子成员

C++ 访问基列表的子成员,c++,list,class,C++,List,Class,是否可以有一个基类的std::list,将少数类型的子类放入其中,并访问迭代的子类成员?如果元素类型是多态的,则是 唯一的问题是,您需要存储指向这些多态对象的指针,因为容器拥有它们的元素,如果您试图将Base添加到您的列表中,它将被复制和切片,从而失去其更派生性质的所有上下文。如果它是一个抽象类(应该是这样),那么代码甚至不会编译 我建议不要使用原始指针,因此我们得到的是: #include <list> #include <memory> #include <io

是否可以有一个基类的
std::list
,将少数类型的子类放入其中,并访问迭代的子类成员?

如果元素类型是多态的,则

唯一的问题是,您需要存储指向这些多态对象的指针,因为容器拥有它们的元素,如果您试图将
Base
添加到您的列表中,它将被复制和切片,从而失去其更派生性质的所有上下文。如果它是一个抽象类(应该是这样),那么代码甚至不会编译

我建议不要使用原始指针,因此我们得到的是:

#include <list>
#include <memory>
#include <iostream>

struct Base
{
   virtual ~Base() {}
   virtual void foo() = 0;
};

struct Derived1 : Base
{
   void foo() { std::cout << "Lol!\n"; }
};

struct Derived2 : Base
{
   void foo() { std::cout << "Haha!\n"; }
};

int main()
{
   typedef std::list<std::unique_ptr<Base>> list_type;

   list_type l;
   l.emplace_back(new Derived1());
   l.emplace_back(new Derived2());
   l.emplace_back(new Derived2());
   l.emplace_back(new Derived1());

   for (auto& x : l)
      x->foo();      // <-- this is a VIRTUAL function call!
}
#包括
#包括
#包括
结构基
{
虚拟~Base(){}
虚拟void foo()=0;
};
结构Derived1:Base
{
void foo(){std::cout如果元素类型是多态的,那么

唯一需要注意的是,您需要存储指向这些多态对象的指针,因为容器拥有它们的元素,如果您试图将
Base
添加到您的列表中,它将被复制和切片,从而失去其派生性质的所有上下文,则代码甚至无法编译

我建议不要使用原始指针,因此我们得到的是:

#include <list>
#include <memory>
#include <iostream>

struct Base
{
   virtual ~Base() {}
   virtual void foo() = 0;
};

struct Derived1 : Base
{
   void foo() { std::cout << "Lol!\n"; }
};

struct Derived2 : Base
{
   void foo() { std::cout << "Haha!\n"; }
};

int main()
{
   typedef std::list<std::unique_ptr<Base>> list_type;

   list_type l;
   l.emplace_back(new Derived1());
   l.emplace_back(new Derived2());
   l.emplace_back(new Derived2());
   l.emplace_back(new Derived1());

   for (auto& x : l)
      x->foo();      // <-- this is a VIRTUAL function call!
}
#包括
#包括
#包括
结构基
{
虚拟~Base(){}
虚拟void foo()=0;
};
结构Derived1:Base
{

void foo(){std::cout是的,这是可能的-但请确保存储指针而不是值,以避免:


与其存储原始指针,不如使用某种智能指针,根据需要调用
delete
。C++11具有各种智能指针,但请确保!

是的,这是可能的-但请确保存储指针而不是值,以避免:


与其存储原始指针,不如使用某种智能指针,根据需要调用
delete
。C++11具有各种智能指针,但请确保!

您不能将
派生的
放入
标准::列表,因为,您可以使用指针(或更好的)来执行此操作

我是普通动物
喵喵


您不能将
Derived
放在
std::list
中,因为,但您可以使用指针(或更好的方法)来执行此操作

我是普通动物
喵喵


你应该能够将它转换为正确的类型,如此确定。你尝试了什么,为什么失败?你应该能够将它转换为正确的类型,如此确定。你尝试了什么,为什么失败?呸,你打败了我,因为我在正确处理C++11混乱时挂断了。呸,你打败了我,因为我挂断了获取C++11的电话好的。你可以用
l.emplace\u back(新衍生1)
@MikeSeymour:哦,真的。谢谢。谢谢!那很有用。你可以用
l.emplace\u back(新衍生1)
@MikeSeymour:哦,真的。谢谢!那很有用
DerivedA::f
DerivedB::f
std::list<Base*> l;
l.push_back(new Derived); // don't forget to delete it!!
#include <iostream>
#include <list>

struct Animal {
    virtual void say() {
        std::cout <<"I'm generic animal\n";
    }

    virtual ~Animal(){}
};

struct Cat : public Animal {
    virtual void say() {
        std::cout << "Meow\n";
    }
    virtual ~Cat(){}
};

int main() {
    std::list<Animal*> l;
    l.push_back(new Animal);
    l.push_back(new Cat);
    for(Animal* ptr: l) {
        ptr->say();
    }
    for(Animal* ptr: l) {
        delete ptr; //not needed if you use smart pointers.
    }
}