c++ - 通过删除复制构造函数等按值(无指针)在 C++ <vector> 中存储具有相同基类的对象

标签 c++ c++11 default copy-constructor delete-operator

我读过(此处为 https://stackoverflow.com/a/18351550/1474291),可以将继承相同基类的派生类的对象存储在 <vector> 中。 .为了防止对象切片,我需要删除移动构造函数、复制构造函数和复制赋值。

注意:我对按值而不是指针存储对象很感兴趣。

我尝试使用 Visual C++ 2013 和 MinGW(GCC 4.8.2 和 4.9.1)编译以下代码,但代码无法编译。我想在 C++11 中通过使用“删除”、“默认”和旧方法来做到这一点。

实现它的正确方法是什么? (实际上 C++ 编译器是否正确支持“删除”和“默认”?)

这是我的示例代码:

#include <iostream>
#include <vector>

using namespace std;

#if __cplusplus > 199711L
    #define CPP11
#endif


class Animal {
public:
    Animal() {
        cout << "Making animal:";
    }
    virtual ~Animal() {
        cout << "Send the animal home!";
    }

#ifdef CPP11
public:
    Animal(Animal&&) = delete;
    Animal(Animal const&) = delete;
    Animal& operator=(Animal&) = delete;
#else // C++98
private:
    Animal(Animal const&);
    Animal& operator=(Animal&);
#endif // CPP11

public:
    virtual void speak() {
        cout << "I am an animal!";
    }
};

class Dog : public Animal {
public:
    Dog() {
        cout << "Making dog:";
    }

    virtual ~Dog() {
        cout << "Send the dog home!";
    }

#ifdef CPP11
public:
    Dog(Dog&&) = default;
    Dog(Dog const&) = default;
    Dog& operator=(Dog&) = default;
#else // C++98
private:
    Dog(Dog const&);
    Dog& operator=(Dog&);
#endif // CPP11

    virtual void speak() {
        cout << "I am a dog!";
    }
};

class Cat : public Animal{
public:
    Cat() {
        cout << "Making cat";
    }

    virtual ~Cat() {
        cout << "Sending the cat home!";
    }

#ifdef CPP11
public:
    Cat(Cat&&) = default;
    Cat(Cat const&) = default;
    Cat& operator=(Cat&) = default;
#else // C++98
private:
    Cat(Cat const&);
    Cat& operator=(Cat&);
#endif // CPP11

    virtual void speak() {
        cout << "I am a cag!";
    }
};

int main()
{
    vector<Animal> animals;

    for (int i = 0; 10 > i; i++) {
        Dog dog;
        animals.push_back(dog);
        Cat cat;
        animals.push_back(cat);
    }

#ifdef CPP11
    for (Animal& animal: animals) {
        animal.speak();
    }
#else
    for (std::vector<Animal>::iterator currentAnimal = animals.begin();
         currentAnimal != animals.end();
         ++currentAnimal) {
        currentAnimal->speak();
    }

#endif // CPP11

    return 0;
}

最佳答案

我认为您遗漏的一点是容器需要为其包含的每个元素留出特定数量的内存。因此容器的元素具有固定大小

现在您想将不同大小的对象填充到那些固定大小的盒子中。你看到这是要去哪里了吗?

每当您尝试将大于其基类的派生对象填充到旨在保存基类大小的对象的变量(读取容器元素)中时,您就会遇到切片。

关于c++ - 通过删除复制构造函数等按值(无指针)在 C++ <vector> 中存储具有相同基类的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24861445/

相关文章:

c++ - av_seek_frame 仅每 12 帧搜索一次

c++ - 在返回 vector 的循环内使用函数

java - 未找到默认 Activity 启动 Activity 时出错

c++ - 在 C++ 中,如何在静态数组的末尾添加链表?

c++ - 什么是智能指针,我应该什么时候使用它?

c++ - 如何在 c++03 中获得模板参数的最精确表示?

c++ - 定义遍历函数的 const 和非常量版本

c++ - 为什么这个数组的第 0 个索引仍然不等于 0?

java - 如何在 Java 程序中通过 java.net.URL 类监控打开的 URL?

android - 如何解决 Oppo 设备上的 "For your messages security, System message app has been set as the default message app” 问题?