从Vector :: Vector基类继承

时间:2016-10-11 17:21:23

标签: c++ vector

我正在尝试学习C ++中的继承。我正在尝试创建vector::vector的子类,只需要string个指针。

我对指针和引用的控制确实很弱,但我无法解释为什么以下代码将每个string设置为同一地址:

#include <iostream>
#include <vector>
using namespace std;

class StringVector : public vector<void*> {
public:
    void push_back(const string* str) {
        vector::push_back(&str);
    }
    string* operator[](int pos) {
        return (string*)vector::operator[](pos);
    }
};

main() {
    StringVector sv;
    string str1 = "hello";
    string str2 = "world";
    sv.push_back(&str1);
    sv.push_back(&str2);
    for (int i = 0; i < 2; i++)
        cout << sv[i] << " ";
}

当我按原样跑步时,我得到:

0xffffcb68 0xffffcb68

即。同一地址。

当我尝试尊重sv[i]时(即*sv[i]);我得到一个例外。谁能告诉我哪里出错了?

2 个答案:

答案 0 :(得分:7)

您正在推送&str,其中包含指针的地址,因此您推送的类型为string**。更重要的是,你正在存储一个短期变量(指针)的地址 - 一旦你离开你的重载push_back就会被破坏。

立即修复只需更改push_back方法(删除字符串上的const并将指针传递给vector::push_back):

void push_back(string* str) {
    vector::push_back(str);
}

就像完全删除方法并使用继承方法一样好。

话虽如此,从大多数标准容器继承是一个坏主意。只需输入vector即可获得string vector<string*>个指针。

如果你想打印字符串值而不是指针,你需要取消引用它们:

for (int i = 0; i < 2; i++)
    cout << *sv[i] << " ";

答案 1 :(得分:3)

在此功能中

void push_back(const string* str) {
    vector::push_back(&str);
}

你没有推送字符串的地址 - 你将指针的地址推送到字符串。在连续调用中,两个不同的指针可能存储在同一个地方(尽管在不同的时间)。

因为向量需要void*并且任何指针都可以转换为void*,所以编译器没有机会提醒您错误。你可能想要的是使用std::vector<std::string*>std::vector<const std::string*>。你shouldn't inherit from the standard collections;更喜欢将它们用作成员。

考虑这是void*和演员阵容危险的一课: