C++基础语法 类 02

类对象作为成员属性

当类里面有其他类成员属性的时候 初始化 先调用其他类构造函数再调用本类构造函数

析构的时候 先调用本类的析构函数 再调用其他类的析构函数。

复制代码
#include <iostream>
#include <string>
using namespace std;
class Phone {
private:
    string m_name;
public:
    Phone(string name): m_name(name){
        std::cout << "phoneinit " << std::endl;
    }
    ~Phone() {
        std::cout << "~Phone()" << std::endl;

    }
};

class People{
private:
    string m_name;
    Phone1 phone;
public:
    //Phone1 phone = phoneName; 隐式转换调用初始化
    People(string name, string phoneName):m_name(name),phone(phoneName) {
        std::cout << "People1 init " << std::endl;
    }
    ~People() {
        std::cout << "~People1()" << std::endl;
    }
    
};
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    People p("李四","华为");
    

    std::cout << "end!\n";
    return 0;
}
/*
 Hello, World!
 phone1 init
 People1 init
 end!
 ~People1()
 ~Phone1()
 Program ended with exit code: 0
 */

静态成员

静态成员就是在成员变量和成员函数前加上static 称为静态成员

静态成员分为

静态成员变量

所有对象共享同一份数据

在编译阶段分配内存

类内声明类外初始化

复制代码
    /// 静态成员变量不归属于某一个对象 所有本类对象 共享
    /// 访问 类名访问 或者对象访问
    /// 访问权限 私有静态成员变量类外是访问不到的
静态成员函数

所有对象共享同一函数

静态成员函数只能访问静态成员变量

复制代码
#include <iostream>
#include "mathutil.hpp"
#include <string>
#include "People.hpp"
#include "Phone.hpp"
using namespace std;
class TV{
    string m_name;
    /// 静态成员变量是有权限的
    static string id;
    /// 静态方法也是有访问权限的
    static void func3() {
        
    }
    
public:
    /// 静态成员变量不归属于某一个对象 所有本类对象 共享
    /// 访问 类名访问 或者对象访问
    /// 访问权限 私有静态成员变量类外是访问不到的
    /// 类内声明
    static string color;
    static void func() {
        
        /// 静态成员函数可访问静态成员变量 但是不能访问非静态成员变量
        /// 静态成员函数也是有访问权限的
        std::cout << "func" << "color = " << color <<std::endl;
    }
    void func2() {
        std::cout << "func2" << "color = " << color <<std::endl;
    }
};
// 类外初始化
string TV::color = "red";
string TV::id = "12345676";

void test33() {
    TV tv1;
    std::cout << tv1.color << std::endl;
    TV tv;
    tv.color = "black";
    std::cout << tv.color << std::endl;
    
    tv.func();
    
    TV::func();
}
void test34() {
    TV::color = "brown";
    //TV::id;//'id' is a private member of 'TV'
    std::cout << TV::color << std::endl;
}
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test33();
    test34();
    std::cout << "end!\n";
    return 0;
}

this指针

this指针 指向被调用的成员函数所属的对象

this指针是隐含在每一个非静态成员函数内的一种指针

this指针不需要定义直接使用即可

this指针用途

1.当形参名和成员变量同名时 用this指针调用成员变量做区分

2.在类的非静态成员函数中返回对象本身 可使用 return *this

//类内的成员变量和成员函数分开存储

//只有非静态成员变量才属于类的对象上

复制代码
#include <iostream>
#include "mathutil.hpp"
#include <string>
#include "People.hpp"
#include "Phone.hpp"
using namespace std;
//类内的成员变量和成员函数分开存储
//只有非静态成员变量才属于类的对象上
class Person2{
    
    int m_a; /// 非静态成员属于类的对象上
    static int m_b; //静态成员变量 不属于类的对象上
    void func() {// 非静态成员函数 不属于类的对象上
        
    }
};
int Person2::m_b = 10;

void test36() {
     // 空对象占用内存空间为1
    // c++ 编译器会给每个空对象也分配一个字节空间 是为了区分空对象占内存的位置
    // 每个空对象也应该有一个独一无二的内存地址
    std::cout << sizeof(Person2) << std::endl;
    Person2 p;
    std::cout << sizeof(p) << std::endl;
    /*
     Hello, World!
     1
     1
     end!
     Program ended with exit code: 0
     */
}
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";

    test36();

    std::cout << "end!\n";
    return 0;
}

this 指针

复制代码
#include <iostream>
#include "mathutil.hpp"
#include <string>
#include "People.hpp"
#include "Phone.hpp"
using namespace std;
class Person3{
public:
    int age;
    Person3(int age){
        // this 指针指向的是被调用的成员函数所属的对象 也就是属于当前对象
        this->age = age;
    }
    /// 链式调用
    Person3& changeAge(int num) {
        this->age = this->age +  num;
        return  *this;
    }
};

void test37() {
    Person3 p(21);
    p.changeAge(12).changeAge(12).changeAge(12);
    std::cout << p.age;

}

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test37();

    std::cout << "end!\n";
    return 0;
}

空指针

复制代码
class Person3{
public:
    int age;
    Person3(int age){
        // this 指针指向的是被调用的成员函数所属的对象 也就是属于当前对象
        this->age = age;
    }
    /// 链式调用
    Person3& changeAge(int num) {
        this->age = this->age +  num;
        return  *this;
    }
    
    void info() {
        if (this == nullptr) {
            return;
        }
        std::cout << this->age << std::endl;
    }
};

void test37() {
    Person3 *p1 = NULL;
    p1->info();
    
    Person3 p(21);
    p.changeAge(12).changeAge(12).changeAge(12);
    std::cout << p.age;

}

const 修饰成员函数

常函数:

成员函数后加const后我们称这个函数为常函数。

常函数内不可以 修改成员属性。

成员属性声明时加关键字mutable后 在常函数中依然可以修改

常对象:

声明对像前加const称该对象为常对象

常对象只能调用常函数

复制代码
#include <iostream>
#include <string>
using namespace std;
class Person4{
public:
    int m_A;
    mutable int m_B;
    Person4(int a,int b){
        m_A = a;
        m_B = b;
    }
    // this 指针的本质 是指针常量 指针的指向是不可以修改的
    // 在成员函数后加const 修饰的是 this指针 让指针指向的值不可以修改 const Person4* const this
    void showPerson() const{
        //this  = nullptr; //Expression is not assignable  this指针的指向是不可以修改的
        //this -> m_A = 10;//Cannot assign to non-static data member within const member function 'showPerson'
    }
    void changeValue() const {
        this->m_B = 20;
        //this->m_A = 10;//Cannot assign to non-static data member within const member function 'changeValue'
    }
    void func() {
        
    }
    
    
};

void test38() {
    const Person4 p(2,5); //常对象
   //p1.m_A = 100; 常对象不 能访问非常变量
    p.m_B = 100;//常对象只能访问常变量
    p.changeValue();
    //p.func(); // 常对象不能调用非常函数
}

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    test38();
    std::cout << "end!\n";
    return 0;
}

友元函数

全局函数做友元

复制代码
#include <iostream>
using namespace std;
class A {
    // 友元函数可以访问类的私有属性或者方法
    friend void changeAPrivateValue(A &a);
private:
    int m_a;
    void func() {
        std::cout << "func" << std::endl;
    }
public:void changeAPrivateValue(A &a);
    A(int a,int b):m_a(a),m_b(b){
        
    }
    int m_b;
    
};
void changeAPrivateValue(A &a) {
    a.func();
    std::cout << a.m_a << std::endl;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    A a(11,33);
    changeAPrivateValue(a);


    std::cout << "end!\n";
    return 0;
}

类作为友元

复制代码
#include <iostream>
#include "mathutil.hpp"
#include <string>
#include "People.hpp"
#include "Phone.hpp"
using namespace std;
// 友元类
class BClass;
class C {
                    
public:
    void visit();
    BClass *m_b;
    C();
};
class BClass{
    /// 友元类
    friend class  C;
private:
    int m_a;
    void func(){
        std::cout << "fuc" << std::endl;
    }
public:
    BClass();
    int m_b;
    void func2() {
        std::cout << "fuc2" << std::endl;
    }
};
// 成员函数放类外
BClass::BClass() {
    
}
C::C() {
    m_b = new BClass;
}
void C::visit() {
    m_b->m_b = 10;
    m_b -> m_a = 33;
    std::cout << m_b->m_b << std::endl;
    std::cout  << m_b -> m_a  << std::endl;
}


int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    C c;
    c.visit();

    std::cout << "end!\n";
    return 0;
}

成员函数做友元

复制代码
#include <iostream>
#include <string>
using namespace std;
class EClass;
class DClass {
public:
    DClass();
    EClass *eclass;
    void visit();
    void visit2();
};
class EClass {
    ///告诉编译器DClass 类的visit2 作为你本类的 友元函数 可以访问本类的 私有成员
    friend void DClass::visit2();
private:
    int m_a;
    
public:
    EClass();
    int m_b;
    
};
EClass :: EClass() {
    m_a = 20;
    m_b = 30;
}
DClass:: DClass() {
    eclass = new EClass;
}
void DClass:: visit() {
    std::cout << eclass->m_b << std::endl;
    // 不能访问私有成员
}
void DClass:: visit2() {
    // 能访问私有成员也能访问非私有成员
    std::cout << eclass->m_b << std::endl;
    std::cout << eclass->m_a << std::endl;

}
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    DClass dclass;
    dclass.visit();
    dclass.visit2();
    std::cout << "end!\n";
    return 0;
}
相关推荐
林开落L17 分钟前
库制作与原理(下)
linux·开发语言·centos·库制作与原理
fengfuyao9851 小时前
基于MATLAB的GUI实现人脸检测、眼睛检测以及LBP直方图显示
开发语言·计算机视觉·matlab
蒋星熠1 小时前
C++零拷贝网络编程实战:从理论到生产环境的性能优化之路
网络·c++·人工智能·深度学习·性能优化·系统架构
CHANG_THE_WORLD1 小时前
# C++ 中的 `string_view` 和 `span`:现代安全视图指南
开发语言·c++
雨落倾城夏未凉1 小时前
9.c++new申请二维数组
c++·后端
Franklin1 小时前
Python界面设计【QT-creator基础编程 - 01】如何让不同分辨率图像自动匹配graphicsView的窗口大小
开发语言·python·qt
雨落倾城夏未凉2 小时前
8.被free回收的内存是立即返还给操作系统吗?为什么?
c++·后端
雨落倾城夏未凉2 小时前
6.new和malloc的区别
c++·后端
郝学胜-神的一滴2 小时前
深入理解QFlags:Qt中的位标志管理工具
开发语言·c++·qt·程序人生
柯南二号2 小时前
【Java后端】MyBatis-Plus 原理解析
java·开发语言·mybatis