调整 std::vector<AbstractClass*> 的大小
Resize a std::vector<AbstractClass*>
这是我的理解,我们永远不能实例化一个抽象类在C++
或同样一个接口在Java
。这是有意义的,因为我们有不提供实现的"纯虚"函数,因此我们只能实例化这个类/接口的子类,这些子类遵循抽象类形成的契约。考虑下面的代码:
#include <iostream>
#include <vector>
using namespace std;
class AbstractClass {
public:
AbstractClass() {
cout << "Instantiating" << endl;
}
virtual void pureVirtualFunction() = 0;
void testMe() {
cout << "test" << endl;
}
};
int main() {
vector<AbstractClass*> v;
v.resize(100);
cout << v.size() << endl;
v[0]->testMe();
v[0]->pureVirtualFunction(); //segfault on my machine
return 0;
}
让我困惑的是,当我在我的计算机上运行这个程序时,我实际上可以调整向量的大小。我一直认为std::vector::resize
实例化了一些元素,从而调用每个元素的构造函数,但进一步的研究表明,构造函数实际上并没有被调用(我的stdout也没有显示100倍的"实例化"字符串)。
所以如果std::vector::resize
为这些新对象分配空间,并允许我在每个对象上实际调用方法,它们如何没有完全实例化?我想我甚至不能在抽象类的向量上调用resize()
,但我可以,我认为因为它们没有完全初始化。有人能解释一下这里发生了什么吗?
编辑:
Brain放屁…忘记了指针向量,当调整大小时,实际上并不分配new
元素,因为指针可以在没有分配元素的情况下创建,但是…为什么我仍然可以调用一个指针上的成员函数到一个类,其中没有实例化?
其他的答案已经说了你的代码有什么问题,我在这里回答编辑:
然而…为什么我仍然可以在指针上调用成员函数类中未实例化的?
你是指这部分吗?
v[0]->testMe();
v[0]->pureVirtualFunction(); //segfault on my machine
基本上,因为v[0]
没有指向一个有效的对象,但试图调用testMe()
已经是未定义的行为。
它没有分段错误的唯一原因是因为你(不)幸运,编译器重写了你的代码。方法testMe()
的主体根本不需要*this
对象,因此编译器只会将其替换为cout
调用。因为没有尝试访问一些无效的this
指针,所以还没有段故障。然后,在调用第二个方法时,编译器需要检查无效this
指针的虚函数表,这会导致段错误。不要依赖testMe()
的行为,这仍然是未定义的行为,任何事情都可能发生
您的vector
的value_type
是AbstractClass*
-也就是说,向量包含指针可以是nullptr
,指向AbstractClass
派生的有效实例或内存中的随机位置的指针。
vector::resize(N)
创建N
默认初始化的元素,同样,向量的value_type
是*
,所以它将创建nullptr
的N
实例。
AbstractClass::testMe
是非虚成员函数。因此,在底层,它只是一个简单的函数,将一个隐藏的this
指针作为其第一个参数。
testMe
的主体本身不访问抽象类的任何元素,所以它永远不会对 this
解除引用。
v[0]->testMe();
调用AbstractClass::testMe(nullptr, );
,不取消对this
的引用。
v[0]->pureVirtualFunction(); //segfault on my machine
尝试解引用nullptr
以找到v[0]
s vtable => crash.
您制作的矢量是AbstractClass *
,而不是AbstractClass
。
指针可以在没有对象指向的情况下创建。
由于函数是虚函数,这些指针可以指向派生类的对象,这些对象不再是抽象的,因此调用将是合法的。
只有当您最终执行它时,系统才会跳过vptr表中的null并转储
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- C 字符串比较“祝您好运”&gt;“再见”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- C 操作员&gt;&gt;与突变器过载
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 是否需要使用 - &gt;运算符在C 中调用成员函数时
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- 错误c++visual studio c2227左侧'->;Init';必须指向类/结构/联合/泛型类型
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- ``这个''不能用this-&gt;指针变量
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 使用shared_ptr<字符串>转换为一个无序集合<字符串>
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到