• C++的struct和class的区别


    1. C++的struct和class的区别

    差异特性structclass
    成员访问范围默认public默认private
    继承关系访问范围默认public默认private
    {}初始化1、纯数据或纯数据+普通方法的结构体支持;2、带构造函数或虚方法的结构体不支持不支持

    1.1 成员访问范围的差异

    1. struct

    struct Person {
        int age;
    }
    Person person = new Person();
    person.age = 12;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可以正常的编译和执行。

    2. class

    class Person {
        int age;
    }
    Person person = new Person();
    person.age = 12; // 编译出错,应改为public int age;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    【扩展】如果不增加public关键字,又想在某个类如ClassA中能访问到这个Person类中的成员,可以通过友元类(friend class Xxx)来将Person中的private和protected的成员共享出去。
    Person类可以这么编写:

    struct Person {
       	 friend class ClassA;
         int age;
    }
    Person person = new Person();
    person.age = 12;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在ClassA中,就可以访问Person中的所有成员了。

    void ClassA:setAge() {
    	Person *person = new Person();
    	person->age = 12;
    }
    
    • 1
    • 2
    • 3
    • 4

    关于友元类的使用,可见c++论坛:https://cplusplus.com/forum/beginner/147733/

    1.1 继承关系访问范围的差异

    指的是子对象是否可访问到父对象中的成员。

    1. struct : struct

    struct SBase {
    public:
        int age = 0;
        SBase() = default;
        virtual ~SBase() = default;
    };
    
    struct Person : SBase {
    public:
        Person() = default;
        virtual ~Person() = default;
    };
    
    int main(int argc, const char **argv)
    {
        Person* child = new Person();
        child->age = 1;
        fprintf(stdout, "test: age=%d\n", child->age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    访问正常。
    在这里插入图片描述

    2. struct : class

    class CBase {
    public:
        int age = 0;
        CBase() = default;
        virtual ~CBase() = default;
    };
    
    struct Person : CBase {
    public:
        Person() = default;
        virtual ~Person() = default;
    };
    
    int main(int argc, const char **argv)
    {
        Person* child = new Person();
        child->age = 1;
        fprintf(stdout, "test: age=%d\n", child->age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    访问正常。

    3. struct : private class

    class CBase {
    public:
        int age = 0;
        CBase() = default;
        virtual ~CBase() = default;
    };
    
    struct Person : private CBase {
    public:
        Person() = default;
        virtual ~Person() = default;
    };
    
    int main(int argc, const char **argv)
    {
        Person* child = new Person();
        child->age = 1;
        fprintf(stdout, "test: age=%d\n", child->age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    编译错误:不可访问。
    在这里插入图片描述

    4. class : class

    class CBase {
    public:
        int age = 0;
        CBase() = default;
        virtual ~CBase() = default;
    };
    
    class Person : CBase {
    public:
        Person() = default;
        virtual ~Person() = default;
    };
    
    int main(int argc, const char **argv)
    {
        Person* child = new Person();
        child->age = 1;
        fprintf(stdout, "test: age=%d\n", child->age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    编译错误:不可访问。

    5. class : public class

    class CBase {
    public:
        int age = 0;
        CBase() = default;
        virtual ~CBase() = default;
    };
    
    class Person : public CBase {
    public:
        Person() = default;
        virtual ~Person() = default;
    };
    
    int main(int argc, const char **argv)
    {
        Person* child = new Person();
        child->age = 1;
        fprintf(stdout, "test: age=%d\n", child->age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    访问正常。

    6. class : struct

    struct SBase {
    public:
        int age = 0;
        SBase() = default;
        virtual ~SBase() = default;
    };
    
    struct Person : SBase {
    public:
        Person() = default;
        virtual ~Person() = default;
    };
    
    int main(int argc, const char **argv)
    {
        Person* child = new Person();
        child->age = 1;
        fprintf(stdout, "test: age=%d\n", child->age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    访问正常。

    7. class : public struct

    struct SBase {
    public:
        int age = 0;
        SBase() = default;
        virtual ~SBase() = default;
    };
    
    struct Person : public SBase {
    public:
        Person() = default;
        virtual ~Person() = default;
    };
    
    int main(int argc, const char **argv)
    {
        Person* child = new Person();
        child->age = 1;
        fprintf(stdout, "test: age=%d\n", child->age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    访问正常。

    【总结】
    1)子为class的,要想访问到父的public成员,需要加public关键字,即class: public xxx
    2)子为struct,可加可不加public,都能访问到父类/结构体的成员

    1.3 {}初始化的差异

    1. struct – 纯数据+一般方法

    struct StructA {
        void send();
        int a;
        long b;
        string str;
    };
    
    void StructA::send()
    {
        fprintf(stdout, "StructA: sending...\n");
    }
    
    int main(int argc, const char **argv)
    {
        StructA aS = {12, 34, "a test"};
        aS.send();
        fprintf(stdout, "StructA: a=%d, b=%ld, str=%s\n", aS.a, aS.b, aS.str.c_str());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    可直接用{}初始化数据:
    在这里插入图片描述

    2. struct – 带构造函数

    struct StructA {
        void send();
        int a;
        long b;
        string str;
        StructA();
    };
    
    void StructA::send()
    {
        fprintf(stdout, "StructA: sending...\n");
    }
    
    int main(int argc, const char **argv)
    {
        StructA aS = {12, 34, "a test"};
        aS.send();
        fprintf(stdout, "StructA: a=%d, b=%ld, str=%s\n", aS.a, aS.b, aS.str.c_str());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    编译失败:
    在这里插入图片描述

    3. struct – 带虚方法

    struct StructA {
        void virtual send();
        int a;
        long b;
        string str;
    };
    
    void StructA::send()
    {
        fprintf(stdout, "StructA: sending...\n");
    }
    
    int main(int argc, const char **argv)
    {
        StructA aS = {12, 34, "a test"};
        aS.send();
        fprintf(stdout, "StructA: a=%d, b=%ld, str=%s\n", aS.a, aS.b, aS.str.c_str());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    编译失败:
    在这里插入图片描述

    4. class

    class ClassA {
        int a;
        long b;
        string str;
    };
    
    int main(int argc, const char **argv)
    {
        ClassA cA = {12, 34, "a test"};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    编译失败:
    在这里插入图片描述

    2. 拓展:C和C++的struct的区别

    差异特性CC++
    成员函数不支持支持
    静态成员不支持支持
    成员访问范围默认public,如果结构体在源文件中定义的,外部也访问不到默认private
    初始化数据成员不支持支持
  • 相关阅读:
    因子图优化及GTSAM中IMU预积分接口
    详解“协方差”与“相关系数”
    王者荣耀改名神器助手微信小程序源码下载,支持流量主模式
    ByteBuffer杂记
    全网最全的 Java 面试题内容梳理(持续更新中)
    【秋季热身赛】No.2.数字朋友 -- Java Version
    如何做一个基于微信在线教育学习小程序系统毕业设计毕设作品
    『微信小程序』从0到1常用组件
    Linux终将取代Unix?富士通确认Unix系统和大型机的结束时间
    数据分析实战 | 线性回归——女性身高与体重数据分析
  • 原文地址:https://blog.csdn.net/FussyCat/article/details/126227664