C++对象模型和this指针

成员变量和成员函数分开存储

在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象,其余都存储在类中

当创建一个类的对象时,会为对象分配一块内存空间,用于存储成员变量。每个对象都有自己的成员变量副本,这些变量存储在对象的内存空间中,并且在对象的声明周期中保持存在(这里的成员变量为非静态成员变量)。

成员函数是类的一部分,它们并不存储在对象的内存空间中,而是存储在类的代码段

类的代码段是指类的定义和成员函数的代码部分,它定义了类的结构,成员变量和成员函数的声明和实现,类的代码段是静态的,在编译时被编译器处理,并在程序执行时被装载到内存中,它是共享的,意味着所有该类的的对象都使用相同的代码。

空对象占用内存空间为1个字节,因为C++编译器会给每个空对象也分配一个字节空间,为了区分空对象内存的位置。

class Person{
​
}
​
class Person1{
public:
    int a; //非静态成员变量属于类的对象
    static int b; //静态成员函数属于类,可以直接通过类名进行访问
    void func(){} //非静态成员函数属于类
    static void func1(){} //静态成员函数属于类,也可以直接通过类名进行访问
}
​
int main(){
    Person p;
    cout << sizeof(p) << endl; // 1
    Person1 p1;
    cout << sizeof(p1) << endl; //4
}

this指针

this是C++特殊的对象指针,this指针指向正在调用成员函数的对象

this指针是一个隐式参数,不需要定义,直接使用即可

#include <iostream>
class MyClass {
public:
    void printAddress() {
        std::cout << "当前对象的地址为: " << this << std::endl;
    }
​
    void printValue() {
        std::cout << "当前对象的值为: " << value << std::endl;
    }
​
private:
    int value;
};
​
int main() {
    MyClass obj1;
    obj1.printAddress(); // 输出当前对象的地址
    obj1.printValue();   // 输出当前对象的值
​
    MyClass obj2;
    obj2.printAddress(); // 输出当前对象的地址
    obj2.printValue();   // 输出当前对象的值
​
    return 0;
}

this指针的用途

  • 当形参和成员变量同名时,可以用this指针来区分

class Person{
private:
    int age;
public:
    Person(int age){
        this->age = age;     //若不用this则没有对成员变量进行成功初始化
    }
};
  • 在类的非静态成员函数中返回对象本身,可以使用return *this,实现链式调用

class MyClass{
public:
    int count;
    MyClass& addCount(){ //此处要是使用MyClass作为返回值的话,那么下面打印就是1,
    //因为值返回相当于重复调用拷贝构造函数
        this->count += 1;
        return *this;
    }
};
int main(){
    MyClass obj;
    obj.addCount().addCount().addCount();
    cout << obj.count << endl; //3
}

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您想在双击树模型的某一项后将选中的子窗口变为mdiarea控件的活动窗口,可以使用QAbstractItemView中的doubleClicked()信号结合QStandardItemModel和QMdiArea来实现。以下是一个示例: ```c++ connect(myTreeView, &QTreeView::doubleClicked, this, [=](const QModelIndex &index){ QStandardItemModel *model = qobject_cast<QStandardItemModel*>(myTreeView->model()); QStandardItem *item = model->itemFromIndex(index); QWidget *widget = item->data(Qt::UserRole).value<QWidget*>(); if(widget) { QMdiSubWindow *subWindow = mdiArea->findChild<QMdiSubWindow*>(widget->objectName()); if(subWindow) { subWindow->setFocus(); } } }); ``` 在上面的示例中,我们连接了QTreeView的doubleClicked()信号,当用户在视图中双击某一项时,将会调用一个lambda表达式。在此表达式中,我们首先获取QStandardItemModel和QStandardItem,然后获取存储在树模型中的QWidget指针。接下来,我们使用QWidget的objectName()函数查找QMdiSubWindow,并将其设置为活动窗口。 请注意,这需要在将QWidget指针存储到树模型时将其命名为与QMdiSubWindow的objectName属性相同。例如: ```c++ QStandardItem *item = new QStandardItem("My Widget"); item->setData(QVariant::fromValue<QWidget*>(widget), Qt::UserRole); item->setEditable(false); item->setToolTip("Double click to select"); item->setObjectName(widget->objectName()); ``` 在上面的示例中,我们使用了QWidget的objectName()函数作为QStandardItem的对象名称,并使用setData()函数将QWidget指针存储到树模型中。这使得我们可以轻松地使用findChild()函数查找QMdiSubWindow。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值