不能将数组运算符用于基于数组的指针(读取访问冲突)
can't use array operator to array-based pointers (read access violation)
基本上我想要实现的是使用指针,避免使用 new
关键字来获得与某些其他语言相同的复制行为(运算符 =
将右操作数的 ref 分配给如果我们谈论对象,左边的那个,类似于 shared_ptr
应该提供的)。如果我不使用数组运算符 []
,我要展示的内容似乎会起作用。为什么会发生这种情况,我该如何解决?
// Declaration way before
std::vector<int>* test;
test = &std::vector<int>();
(*test)[1] = 0;
// Declaration way before
std::map<std::string, int>* test;
test = &std::map<std::string, int>();
(*test)["a"] = 0;
错误发生在两者的最后一行。
您正在将对临时向量的引用分配给您的指针。临时对象立即死亡,您的指针悬空。
您还尝试访问具有 0
大小的矢量的第二个元素。
你可以试试这个,但我们已经不是new
delete
时代了
std::vector<int>* test;
test = new std::vector<int>(2);
(*test)[1] = 0;
// done with test
delete test;
test = &std::vector<int>();
这不是有效的 C++。您不能使用临时地址。
不幸的是,作为扩展 Visual Studio 确实允许您这样做;您得到的指针 立即悬空 (因为临时指针在该行的末尾消失)。然后,您尝试对向量(不存在)执行的所有操作都具有未定义的行为。
(即使它是一个有效的指针,您也在尝试索引不存在的元素。)
只要在范围内的某处保留适当的命名对象,您就可以做您想做的事。您可以获得指向该对象的指针,并在各处获取您的引用语义。但是,这很危险,因为很难确保 pointed-to 对象在需要时处于活动状态。这就是智能指针存在的原因。
在 C++ 中,坚持使用值语义会更好。该语言最好按设计使用。
can't use array operator to array-based pointers
你可以,如果你的指针指向一个对象。你的没有。
to use pointers, avoiding new keyword to obtain the same copying behaviour like in some other languages
你没有真正展示你想要什么行为,也没有说你想模仿哪种语言,但总的来说:用语言 B 编写语言 A 代码是个坏主意。两者会有不同的约定俗成和微妙之处。
如果你做坚持编写看起来像另一种语言的 C++,你需要弄清楚你需要什么特定的行为,以及如何在 C++ 中实现它以使其看起来相似.这通常需要大量工作,并且编写看起来符合您需要的方式并且恰好可以编译的 C++ 代码并不是一个充分的解决方案。
由于 Lightness 指出了您的近似错误,我只想提一下,通过编写金丝雀类型来检查您对这些事情的理解是微不足道的,例如
struct Canary {
~Canary() { cout << "Canary dtor\n"; }
Canary() { cout << "Canary default ctor\n"; }
Canary(Canary &&) { cout << "Canary move ctor\n"; }
Canary(const Canary &) { cout << "Canary copy ctor\n"; }
Canary& operator=(Canary &&) { cout << "Canary move assignment\n"; return *this; }
Canary& operator=(const Canary &) { cout << "Canary copy assignment\n"; return *this; }
};
Canary *c = &Canary();
现在您可以在调试器中轻松单步执行代码,或者只是 运行 并观察输出...
基本上我想要实现的是使用指针,避免使用 new
关键字来获得与某些其他语言相同的复制行为(运算符 =
将右操作数的 ref 分配给如果我们谈论对象,左边的那个,类似于 shared_ptr
应该提供的)。如果我不使用数组运算符 []
,我要展示的内容似乎会起作用。为什么会发生这种情况,我该如何解决?
// Declaration way before
std::vector<int>* test;
test = &std::vector<int>();
(*test)[1] = 0;
// Declaration way before
std::map<std::string, int>* test;
test = &std::map<std::string, int>();
(*test)["a"] = 0;
错误发生在两者的最后一行。
您正在将对临时向量的引用分配给您的指针。临时对象立即死亡,您的指针悬空。
您还尝试访问具有 0
大小的矢量的第二个元素。
你可以试试这个,但我们已经不是new
delete
时代了
std::vector<int>* test;
test = new std::vector<int>(2);
(*test)[1] = 0;
// done with test
delete test;
test = &std::vector<int>();
这不是有效的 C++。您不能使用临时地址。
不幸的是,作为扩展 Visual Studio 确实允许您这样做;您得到的指针 立即悬空 (因为临时指针在该行的末尾消失)。然后,您尝试对向量(不存在)执行的所有操作都具有未定义的行为。
(即使它是一个有效的指针,您也在尝试索引不存在的元素。)
只要在范围内的某处保留适当的命名对象,您就可以做您想做的事。您可以获得指向该对象的指针,并在各处获取您的引用语义。但是,这很危险,因为很难确保 pointed-to 对象在需要时处于活动状态。这就是智能指针存在的原因。
在 C++ 中,坚持使用值语义会更好。该语言最好按设计使用。
can't use array operator to array-based pointers
你可以,如果你的指针指向一个对象。你的没有。
to use pointers, avoiding new keyword to obtain the same copying behaviour like in some other languages
你没有真正展示你想要什么行为,也没有说你想模仿哪种语言,但总的来说:用语言 B 编写语言 A 代码是个坏主意。两者会有不同的约定俗成和微妙之处。
如果你做坚持编写看起来像另一种语言的 C++,你需要弄清楚你需要什么特定的行为,以及如何在 C++ 中实现它以使其看起来相似.这通常需要大量工作,并且编写看起来符合您需要的方式并且恰好可以编译的 C++ 代码并不是一个充分的解决方案。
由于 Lightness 指出了您的近似错误,我只想提一下,通过编写金丝雀类型来检查您对这些事情的理解是微不足道的,例如
struct Canary {
~Canary() { cout << "Canary dtor\n"; }
Canary() { cout << "Canary default ctor\n"; }
Canary(Canary &&) { cout << "Canary move ctor\n"; }
Canary(const Canary &) { cout << "Canary copy ctor\n"; }
Canary& operator=(Canary &&) { cout << "Canary move assignment\n"; return *this; }
Canary& operator=(const Canary &) { cout << "Canary copy assignment\n"; return *this; }
};
Canary *c = &Canary();
现在您可以在调试器中轻松单步执行代码,或者只是 运行 并观察输出...