C++类指针初始化
class Test
{
public:
void func(){cout << "hahaha" << endl;}
int get(){return a+b;}
Test():a(1),b(2){}
public:
int a,b;
};
而之后编译器会自动将这个类转换成:
class Test
{
int a,b;
};
void _test_func(Test * this);
int _test_get(Test* this);
........
类中的函数被编译器静态编译了,所有非虚函数(虚函数呢?别急,待会会解释到)都可以调用,因为函数地址编译期间已经确定。我们知道,类中的成员函数都是通过this指针调用成员变量的,编译器会将this指针作为默认参数传给类成员函数的,如myclass.function(int a,int b) --> function(&myclass,int a,int b)
添加main函数如下:
int main()
{
Test *p=NULL;
p->func();//正确,没有调用成员变量,没有使用空的this指针
p->get();//错误,this指针为空,通过this指针调用变量所以出错
return 0;
}
运行结果如上,没有调用成员变量的func()函数正确执行,调用了成员变量的get()函数错误。两者其实都传入了空的this指针,前者没出错仅仅是因为没有调用this指针,而后者调用了。(此时p-func()和p->get()等同于func(NULL),get(NULL)......)是对象指针为NULL,而调用成员函数的时候,函数地址是编译期间确定的,成员函数不通过对象指针(也即当前的p指针)去调用,对象指针仅仅作为参数传入函数然后去调用成员变量。
好现在问题来了,如果是虚函数呢,因为虚函数要通过this指针计算vptr,然后找到vtable,然后dispatch。因为this指针为空,所以在找vtable时候就会coredump了。总之这类情况下,一切调用了this指针的函数都会出错,而完全不调用this指针的成员函数则没问题。
总结:任何时候定义指针的时候一定要初始化,这是良好的习惯,这个问题最初是由于当时写程序疏忽造成的,然而错有错着居然编译通过,所以当时一直没发现这个手误,现在追本溯源也算是对c++的内部机制有了更深的了解,不过也提示自己不能有侥幸心理,一定要养成良好的编程习惯,不管对于自己还是对于以后合作的伙伴都是一件好事。
C++类指针初始化的更多相关文章
- C++ 类的多态三(多态的原理--虚函数指针--子类虚函数指针初始化)
//多态的原理--虚函数指针--子类虚函数指针初始化 #include<iostream> using namespace std; /* 多态的实现原理(有自己猜想部分) 基础知识: 类 ...
- C#多态;父类引用指向子类对象;new和override的区别;new、abstract、virtual、override,sealed关键字区别和使用代码示例;c#类的初始化顺序
关于父类引用指向子类对象 例如: 有以下2个类 public class Father { public int age = 70; public static string name = " ...
- C++类构造函数初始化列表
C++类构造函数初始化列表 构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式.例如: class CExample {public: ...
- c++类与初始化,const
--c++类与初始化,const --------------------------------2014/09/04 1. 类的定义(头文件.声明文件)看成类的外部接口,一般写成.h头文件. 2. ...
- C++类构造函数初始化列表(转)
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式.例如: { public: int a; float b; //构 ...
- jvm(2)类的初始化(二)和实例化
深入理解Java对象的创建过程:类的初始化与实例化 对象实例化内存分析: 对内存分配情况分析最常见的示例便是对象实例化: Object obj = new Object(); 这段代码的执行会涉及ja ...
- java类的初始化和构造函数
本人小白一枚,看java类的初始化的时候好晕的说,我觉着书上尽管说的对.但总认为有些信息没说出来,没说清楚,看了好多文章博客的,如今有些感悟,来小写下总结,也算是为以后再次复习种个好果子. 先摘一下书 ...
- C++ 静态成员的类内初始化
一般来说,关于C++类静态成员的初始化,并不会让人感到难以理解,但是提到C++ 静态成员的"类内初始化"那就容易迷糊了. 我们来看如下代码: //example.h #includ ...
- 为什么static成员必须在类外初始化,而不能在类的头文件中初始化
为什么static成员必须在类外初始化 为什么静态成员不能在类内初始化 在C++中,类的静态成员(static member)必须在类内声明,在类外初始化,像下面这样. class A { pri ...
随机推荐
- css3のtext-shadow
text-shadow,让我们大家一起来学习一下吧. 语法: text-shadow:none | <shadow> [ , <shadow> ]* <shadow> ...
- Spring Boot运行原理
概述 本文主要写了下Spring Boot运行原理,还有一个小例子. Spring4.x提供了基于条件来配置Bean的能力,而Spring Boot的实现也是基于这一原理的. Spring Boot关 ...
- CF1025C Plasticine zebra
思路: 不要被骗了,这个操作实际上tm是在循环移位. 实现: #include <bits/stdc++.h> using namespace std; int main() { stri ...
- win10 64位 mysql安装过程出现status显示failed
mysql安装过程出现status显示failed,如下图: 由于我的电脑是64位系统,这里需要升级一个插件,即32位 visual C++ 2013 and visual C++ redistri ...
- WIN32项目中MFC程序窗口居中
//class CMainWindow : public CFrameWnd void CMainWindow::OnSize(UINT nType, int cx, int cy){ CFra ...
- fiddler+willow问题总结
本文纯属用来记录自己学习过程中遇到的坑,如有朋友也遇到,可移步到这里查看是否为该问题导致. fiddler 安装不用说了,到官网直接去下载,自行下载最新版本 willow下载地址:http://qzo ...
- 洛谷 P1334 瑞瑞的木板==P2664 【题目待添加】
题目描述 瑞瑞想要亲自修复在他的一个小牧场周围的围栏.他测量栅栏并发现他需要N(1≤N≤20,000)根木板,每根的长度为整数Li(1≤Li≤50,000).于是,他神奇地买了一根足够长的木板,长度为 ...
- iOS perform action after period of inactivity (no user interaction)
代码看完后感觉非常优秀 http://stackoverflow.com/questions/8085188/ios-perform-action-after-period-of-inactivity ...
- 改变console.log的输出样式
console.log允许你通过css来格式化输出,格式如下: console.log(‘%c字符串%c字符串’, 样式1, [样式2]) 其中”%c”为模板字符串 例子: 1 console.log ...
- 团队作业-Beta冲刺第三天
这个作业属于哪个课程 <https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1> 这个作业要求在哪里 <https ...