继承Vector: Vector基类

Inheritance from Vector::Vector base class

本文关键字:Vector 基类 继承      更新时间:2023-10-16

我正在学习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])时;我得到一个异常。谁能告诉我哪里错了?

您正在推送&str,它采用指针的地址,因此您正在推送的类型是string**。更重要的是,您正在存储一个短寿命变量(指针)的地址-一旦您离开重载的push_back,它就会被销毁。

立即修复是简单地改变push_back方法(删除const在string和传递指针到vector::push_back):

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

,这与简单地完全删除方法并使用继承的方法一样好。

也就是说,从大多数标准容器继承是一个坏主意。您可以通过输入vector<string*>来获得vectorstring指针。

如果要打印字符串值而不是指针,则需要对它们解引用:

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

在这个函数中

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

你没有压入string对象的地址——你压入了指向string对象的指针的地址。在连续的调用中,两个不同的指针可能被存储在同一个位置(尽管在不同的时间)。

因为你的vector对象是void*,而任何指针都可以转换为void*,所以编译器没有机会提醒你的错误。您可能想要使用std::vector<std::string*>std::vector<const std::string*>。你不应该继承标准集合;更倾向于使用它们作为成员。

考虑一下void*和强制类型转换的危险吧!