孔乙己之一----this

2024-01-18 04:18
文章标签 孔乙己

本文主要是介绍孔乙己之一----this,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文作者:sodme
本文出处:http://blog.csdn.net/sodme
声明: 本文可以不经作者同意, 任意复制, 转载, 但任何对本文的引用都请保留文章开始前三行的作者, 出处以及声明信息. 谢谢.

这是一个小问题, 孔乙己一把, 全当自娱. 今天在线上被问到一个问题, 描述如下:

#include 
using namespace std;

class MyClass
{
public:
    MyClass(){};
    ~MyClass(){};
    void print()
    {
       cout << "hello!" << endl;
    }
};

int main()
{
    MyClass * pMyClass;
    pMyClass = new MyClass;
    pMyClass->print();                        // 1: 正确调用
    pMyClass[0].print();                      // 2: 正确调用
    pMyClass[1].print();                      // 3: 错误调用, 但结果正确
    pMyClass[10000000].print();               // 4: 错误调用, 但结果正确

    return 0;
}


这位兄弟有疑问的是: 为什么3和4两种方法, 下标不正确, 而其结果却完全正常? 显示的结果是:
hello!
hello!
hello!
hello!

我把程序改了改, 将类MyClass调整成以下结构:
class MyClass
{
public:
    MyClass(){ data1 =1; data2=2;};
    ~MyClass(){};
    int data1,data2;
    void print()
    {
       cout << "hello! data1: " << data1 << " data2: " << data2 << endl;
    }
};

再次编译(编译环境是gcc 4.2), 执行, 结果如下:
hello! data1: 1 data2: 2
hello! data1: 1 data2: 2
hello! data1: 0 data2: 135153
段错误

这其实又是一个老生常谈的问题. 要搞清这个问题, 就得先弄明白类函数是如何被编译以及如何被执行的? 关于这点, "C++对象模型"上有甚为详细的讲解, 在此一笔带过:
对于类成员函数而言, 并不是一个对象对应一个单独的成员函数体, 而是此类的所有对象共用这个成员函数体, 当程序被编译之后, 此成员函数地址即已确定. 我们常说, 调用类成员函数时, 会将当前对象的this指针传给成员函数. 没错, 一个类, 它的成员函数体只有一份, 而成员函数之所以能把属于此类的各个对象的数据区别开, 就在于每次执行类成员函数时, 都会把当前对象的this指针(也即对象首地址)传入成员函数, 函数体内所有对类数据成员的访问, 都会被转化为this->数据成员的方式.

说到这里, 问题也就清楚了. 当print函数里, 只有"cout << "hello" << endl;"这条语句时, 由于print函数并没有访问对象的任何数据成员, 那么此时传进来的对象this指针实际上是没有任何用处的, 这样的函数, 其特征与全局函数并没有太大区别. 但当后来把类MyClass结构作了调整后, 由于print函数要访问类的数据成员data1和data2, 而类的数据成员, 是伴随着对象声明而产生的, 但是, 我们只new了一个MyClass, 显然, 下标"1"和下标"10000000"的MyClass对象根本不存在, 那们对它们的数据成员访问也显然是非法的.

但是, 还有另一个问题, 当把类MyClass再作一次调整, 成这样:
class MyClass
{
public:
    MyClass(){ data1 =1;};
    ~MyClass(){};
    int data1;
    void print()
    {
       cout << "hello! data1: " << data1 << endl;
    }
};

也就是只含有一个int类型的数据成员时, pMyClass[1].print()的访问结果有时却是正确的(不同的机子上会有不同的结果). 我想, 这个只能解释为地址对齐所造成的了(暂时存疑, 查证中, 欲知后事, 下回分解).


这篇关于孔乙己之一----this的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/618047

相关文章

孔乙己:参数的⑨种写法

孔乙己:参数的⑨种写法 // 这里客串一下:using _Ty = int;1. _Ty 2. const _Ty / _Ty const3. const _Ty& / _Ty const&4. _Ty&5. _Ty&&6. _Ty*7. const _Ty* / _Ty const*8. _Ty*const9. const _Ty*const / _Ty

孔乙己:new的五种写法

孔乙己:new的五种写法 这个是目标类:_INT 拥有一个字面常量构造函数,和一个平凡析构函数 可以从int构造,也可以隐式转换为int 也可以和int比较大小 class _INT{private:int value;public:constexpr explicit _INT(int _Val0 = 0) noexcept:value(_Val0) {}~_INT()

孔乙己教你 Flutter 状态管理的 N 种方法

楔子 话说孔乙己转行做了程序员,听闻近年来大前端比较火,也跟风学了一阵。什么 Vue,React,Angular 都了解一点。这段时间,行业巨头谷歌出了个 Flutter,号称要一套代码搞定整个前端,孔乙己自然不愿放过。 这天孔乙己逛到了掘金社区,里面大佬太多,他怕自己太业余露馅。知道不能和他们谈天,便只好向初学者说话。有一回在我的评论区问道,“你学过 Flutter么?” 我略略回了个表情。

阳光开朗孔乙己,会否奔向大泽乡

前言 🔥学历对职业关系到底有什么影响呢?🔥学历给我们带来了优势吗?🔥到底是什么造成了"孔乙己的长衫"?     孔乙己是中国清代作家鲁迅创作的一篇短篇小说,发表于1919年。这部作品被认为是鲁迅最具代表性和最具影响力的作品之一,也是中国现代文学史上的一部经典之作。孔乙己通过对主人公孔乙己的生活和性格的描写,展现了社会对底层人民的歧视和压迫。孔乙己是一个贫困的酒保,他

从‘孔乙己长衫’现象看社会不公

孔乙已是鲁迅笔下人物,穷困流倒还穿着象征读书人的长衫,迁腐、麻木。最近,大家自我调佩是“当代孔乙己”,学历成为思想负担,找工作时高不成低不就。 认识孔乙己 孔乙己是清朝末年的小贩,生活在贫苦的阶层中。他虽然有才华,却因为出身和贫穷,没有机会接受良好的教育和发展自己的天赋。相反,他被困在社会的底层,只能依靠卖唱度日。孔乙己的长衫,反映了当时社会阶层固化和教育机会不公的现象。 个人看法