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;
}
相关推荐
晓纪同学24 分钟前
QT-简单视觉框架代码
开发语言·qt
威桑24 分钟前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服27 分钟前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生33 分钟前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生36 分钟前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans38 分钟前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手1 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
Chinese Red Guest1 小时前
python
开发语言·python·pygame
一棵星1 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言
别NULL2 小时前
机试题——疯长的草
数据结构·c++·算法