是否可以从不存在的实例调用方法?
Is it possible to call a method from an instance that doesn't exist?
我正在处理的代码:
我有以下代码(在main.cpp中有一个关于索引的错误):
样本.hpp:
#ifndef SAMPLE_HPP
# define SAMPLE_HPP
# include <iostream>
# include <string>
class Sample{
public:
Sample(void);
~Sample(void);
void tellname(void) const;
private:
std::string _name;
};
#endif
示例.cpp:
#include <iostream>
#include "Sample.hpp"
Sample::Sample(void){
this->_name = "testname";
return;
};
Sample::~Sample(void){
return;
}
void Sample::tellname(void) const{
std::cout << "Name : " << this->_name << std::endl;
return;
}
main.cpp
#include "Sample.hpp"
int main(void){
int i;
Sample *test;
test = new Sample[4];
i = 0;
while (i++ < 4) // I know : i++; shouldn't be here
test[i].tellname();
delete [] test;
return 0;
}
如果我编译它,我会得到以下输出:
Name : testname
Name : testname
Name : testname
Name :
我的问题是:
关于最后一行,它调用了一个方法(void Sample::tellname(void)
),但来自不在表范围内的实例(test[4]
不存在)。
但是,即使从中调用tellname()
的实例不存在,它仍然会调用它它只是认为它的_name
字段为空。
这怎么可能?
这只是一个未定义的行为,C++没有对其施加任何要求,因此"任何事情都可能发生"。您所看到的只是一个巧合,没有任何理由:下次运行时,它可能会崩溃,显示nyan-cat等等。
听起来您想知道为什么要调用该函数。在内存中,结构不包含其内部的函数。相反,函数的一个副本被放置在可执行文件的某个位置。因此,当您调用test[4].tellname()
时,实际发生的情况是:地址test + (4 * sizeof(Sample))
被传递给函数tellname()
。该地址的值未定义。
下面是一个例子,让你了解正在发生的事情:
#include <iostream>
struct astruct {
int i = 0;
void prnt()
{
std::cout << i << 'n';
}
};
struct bstruct {
int y = 100;
};
int main()
{
bstruct b;
((astruct*)&b)->prnt();
getchar();
return 0;
}
这里,prnt()
在幕后传递bstruct的地址,并将其视为astruct的地址,因为bstruct中的第一个值是100,所以它打印100。你甚至可以将其简化为:
#include <iostream>
struct astruct {
int i = 0;
void prnt()
{
std::cout << i << 'n';
}
};
int y = 100;
int main()
{
((astruct*)&y)->prnt();
getchar();
return 0;
}
i
从1变为4 include,因为tellname
是const,test[4].tellname()
是Sample::tellname
,而Sample
是一个未定义的结构,所以"名称:"正确打印,然后打印test[4]._name
中的内存,幸运的是,test[4]._name*
指向的内存不是null,甚至是一个结束字符串char。
所以,是的,你很幸运。
相关文章:
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 从基类实例调用派生类方法而不进行强制转换
- 如何在C++从父实例调用子函数
- 为 std::shared_ptr 实例调用 Operator()
- 跨类的多个实例调用函数一次
- 如何从派生类实例调用父类重载函数
- 如何在C++中跨实例调用方法
- 防止同一类的实例调用公共功能(C )
- 使用Objective C类实例调用C函数
- 从结构实例调用变量语法问题C++
- 从基类实例调用派生类方法
- C++从基类实例调用派生函数
- 是否可以从不存在的实例调用方法?
- 如何使用派生类实例调用基类重载的func,
- 为singleton实例调用函数创建一个别名
- 用结构体的所有实例调用函数
- 从继承的类实例调用静态成员
- 当我从类实例调用方法时,我的C程序崩溃了,下面是代码
- 当尝试使用类的实例调用方法时,调试断言错误
- C++:从派生实例调用 base 中的纯虚拟方法重载