我正在尝试学习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]
);我得到一个例外。谁能告诉我哪里出错了?
答案 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*
和演员阵容危险的一课: