C++ [类和对象 - 下]

这篇具有很好参考价值的文章主要介绍了C++ [类和对象 - 下]。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++ [类和对象 - 下]

      

 本文已收录至《C++语言》专栏!
作者:ARMCSKGT

      

C++ [类和对象 - 下]


目录

 

前言

正文

初始化列表

成员变量的定义与初始化

初始化列表的使用

变量定义顺序

explicit关键字

隐式类型转换

自定义类型隐式转换 

explicit 限制转换

关于static

static声明类成员

友元

友元函数

友元函数特殊使用场景

友元类

内部类

概述

特性

匿名对象

编译器对于自定义类型的一些优化

隐式类型转换的优化 

传参优化

返回值优化

说明

合理使用优化

关于对象的理解

最后


前言

前面我们介绍了类和对象的基本概念以及类的六个默认成员函数,这些知识已经为我们搭起了一个基本的类框架,不过类和对象中还有一些小细节需要介绍,本节我们将进入类和对象的收尾阶段!

C++ [类和对象 - 下]


正文

初始化列表


成员变量的定义与初始化

上篇我们学习了构造函数,构造函数是用来初始化成员变量的,而成员变量的定义是在初始化列表,对于一些需要在定义时就赋值的成员,例如 const int x ,这时需要使用初始化列表进行,因为在C++11之前,C++98并不支持在声明列表中给缺省值!

  

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。

    

int num = 0; //在定义时赋初值 - 初始化
num = 1; //被定义后赋值 - 赋值

那么初始化列表与构造函数有什么关系呢?构造函数是对象在实例时就调用的一个函数,初始化列表在构造函数中,会随构造函数一起执行,初始化列表最先执行并将指定的值赋给每个成员变量!如果我们没有显示去写初始化列表编译器仍然会执行初始化列表,只不过内置类型初始化为随机值,自定义类型则调用其默认构造函数

      

示例1:

class Date 
{
public:
    //猜猜下面两个构造函数的区别
    Date() //初始化列表初始化
        :_year(2008)
        ,_month(12)
        ,_day(21)
    {
        _year = 0;
        _month = 0;
        _day = 0;
    }

    Date(size_t year, size_t month, size_t day) //函数内赋值
    { 
        _year = year;
        _month = month;
        _day = day;
    }

private:
    size_t _year;
    size_t _month;
    size_t _day;
};

int main()
{
    Date d1;
    Date d2(1970,1,1);
    return 0;
}
C++ [类和对象 - 下]
使用初始化列表的构造函数
C++ [类和对象 - 下]
未使用初始化列表的构造函数

 示例2:

class Test
{
public:
    Test() //a会被初始化为什么?
        :a(1)
    { }
private:
    int a = 2;
};

int main()
{
    Test t;
    return 0;
}
C++ [类和对象 - 下]
编译器优先使用初始化列表中的初值进行初始化

初始化列表的使用

   

初始化列表:在函数参数()后,函数体前{},以一个(:)冒号开始,接着是一个以(,)逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式,最后一个列表成员后没有任何符号。

//1.所有对象的成员变量都是在初始化列表被定义的
//2.无论是否显示在初始化列表写,每个变量都会在初始化列表中被定义和初始化

class Date
{
public:
    Date(int year = 1970, int month = 1, int day = 1)
        :_year(year) //初始化列表初始化
        , _month(month)
        , _day(day)
    {
        //其他初始化行为    
    }
private:
    int _year;
    int _month;
    int _day;
};

   

注意

  • 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
  • 类中包含以下成员,必须放在初始化列表位置进行初始化:引用成员变量,const成员变量,自定义类型成员且该类没有默认构造函数时(简而言之就是需要在初始化指定初始值的成员变量)

   

//错误示例
class Test2
{
    Test2(int a) {}
};

class Test
{
public:
    Test() {}
private:
    const int num; //这三种成员变量不使用初始化列表初始化是无法编译的!
    int& ref;
    Test2 t;
};

int main()
{
    Test t;
    return 0;
}
C++ [类和对象 - 下]
上述代码编译报错

   

因为构造函数中函数体是以赋值的方式初始化的,在执行赋值语句前,变量需要被定义和初始化,编译器默认的初始化手段是赋随机值,const只能在初始化阶段指定初始值,如果const常亮被赋予随机值是不合理的,这里也突出了构造函数的一些缺陷,为了补足这些缺陷,C++使用初始化列表定义和初始化且初始化列表存在与构造函数中!

       

C++ [类和对象 - 下]
节选自C++之父Scott Meyers名书Effective C++ ( 其中成员初值列就是初始化列表)

所以尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化!


变量定义顺序

  

成员变量既然在初始化列表定义,那定义的顺序是由什么觉得的?

成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关!

class Test
{
public:
    Test() //猜猜a会被初始化为1吗?
        : b(1)
        , a(b)
    {
        cout << a << endl;
    }
private:
    int a = 0;
    int b = 0;
};

int main()
{
    Test t;
    return 0;
}
C++ [类和对象 - 下]
a在b前被定义但是b此时未被初始化所以是随机值

结论:成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

 

所以这里建议:初始化列表顺序与成员变量声明顺序一致


explicit关键字


我们在平时写代码中不妨会涉及类型转换,类的实例化也是,实例化对象时也会发生类型转换!


隐式类型转换

对于两个类型不同的变量,如果要赋值则需要进行类型转换。

int i = 0;
double d = 1.23456;
i = d; //这里会发生隐式类型转换

C++ [类和对象 - 下]


自定义类型隐式转换 

//示例代码
class Test 
{
public:
    //默认构造函数
    Test(int num = 0)
        :_num(num)
    {
        cout << "构造函数" << endl;
    }

    //拷贝构造
    Test(const Test& t)
    {
        _num = t._num;
        cout << "拷贝构造" << endl;
    }

    //赋值重载
    Test& operator=(const Test& t)
    {
        _num = t._num;
        cout << "赋值重载" << endl;
    }

private:
    int _num;
};

int main()
{
    //初始化会成功吗?
    Test t = 10;
    return 0;
}

C++ [类和对象 - 下]

很显然,初始化成功了,但是我想告诉大家,这次初始化调用了构造函数和拷贝构造和两个函数,进行了隐式类型转换然后初始化了 t 对象! 

C++ [类和对象 - 下]

C++ [类和对象 - 下]
实际运行调用

这里大家可能会怀疑,上面解释的明明会调用两个构造函数,但是实际上却只调用了一个构造函数,这里要说明的是:编译器为了优化效率,将10直接对t进行构造(直接构造),这样可以提高效率!

Test t = 10; //这样效率太低了

Test t(10); //编译器优化为直接构造

    

当然如果类初始化时有多参数参与初始化,也支持多参数构造优化!

class Test
{
public:
	Test(int a, int b)
		: _a(a)
		, _b(b)
	{
		cout << "Test()" << endl;
		cout << "_a = " << _a << " " << "_b = " << _b << endl;
	}
private:
	int _a = 0;
	int _b = 0;
};

int main()
{
	Test t = { 1,2 };
	return 0;
}

C++ [类和对象 - 下]


explicit 限制转换

   

铺垫了这么久,重点来了!

有时候我们不想使构造函数方式类型转换进行构造,可以在构造函数前加上 explicit 关键字禁止类型转换

//示例代码
class Test 
{
public:
    //默认构造函数 - explicit修饰限制类型转换行为
    explicit Test(int num = 0)
        :_num(num)
    {
        cout << "构造函数" << endl;
    }

    //拷贝构造
    Test(const Test& t)
    {
        _num = t._num;
        cout << "拷贝构造" << endl;
    }

    //赋值重载
    Test& operator=(const Test& t)
    {
        _num = t._num;
        cout << "赋值重载" << endl;
    }

private:
    int _num;
};

int main()
{
    //初始化会成功吗?
    Test t = 10;
    return 0;
}
C++ [类和对象 - 下]
此时类型转换也不存在了,编译器优化也就不存在了

所以,如果我们想要提高代码的可读和规范性,必要时使用explicit修饰构造函数就能防止实例化时发生类型转换!


关于static


在C语言的学习中,我们知道static是静态修饰,被修饰的变量生命周期增长至程序运行周期!但是我们平时在写代码时static必须得慎用,因为其中有很多细节需要我们考虑!


static声明类成员

   

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。

  

特性

  • 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区。
  • 静态成员变量必须在类外定义和初始化且只能初始化一次,定义时不添加static关键字,类中只是声明
  • 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问。
  • 静态成员函数没有隐藏的this指针,不能访问任何非静态成员(这样就不需要实例化对象,只需要类名就能访问)。
  • 静态成员函数只能访问静态成员,因为没有this指针无法调用其他非静态成员,静态成员函数是为了静态成员变量而生的
  • 静态成员也是类的成员,受public、protected、private 访问限定符的限制。

   

//示例
class Test
{
public:
	//Test()
	//	:a(0) 
	//{}
//不能在初始化列表初始化,因为静态成员a不属于任何一个单独的对象,a被所有对象共享
	static int a; //声明为静态成员
};

int Test::a = 0; //类外定义和初始化静态成员 - 类型 类名::静态成员

int main()
{
	++Test::a; //通过类名 Test::a 访问静态成员
	cout << "Test::a : " << Test::a << endl;
	Test t;
	++t.a; //通过对象 t.a 访问静态成员
	cout << "t.a : " << Test::a << endl;

	return 0;
}

  

重点总结: 静态成员不能调用非静态成员,因为没有this指针,但是非静态成员可以调用静态成员,因为静态成员具有全局属性!


由静态成员的特性,可以求出实例化了多少个对象!

因为实例化对象每次都会调用构造函数,我们可以定义一个静态成员计数器num,每次调用构造函数num就加1,最后就可以完成对构造函数调用次数的统计!


class Test
{
public:
	Test() //默认构造
	{
		cout << "Test()  ";
		++num;
	}

	~Test() //析构函数
	{
		cout << "~Test() ";
		cout << "num = " << num << endl; //打印当前num
	}

	static int num;
};

int Test::num = 0;

int main()
{
	for (int i = 0; i < 10; ++i) //循环进行实例对象
	{
		Test t;
	}
	return 0;
}

C++ [类和对象 - 下]


友元


概述:有些场景下,某些外部函数需要访问类私有和保护成员,友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用

 

友元分为:友元函数和友元类

友元声明关键字: friend


友元函数

将函数使用friend修饰并声明在类中,则此函数称为该类的友元函数!

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明。

//区别示例
class Test
{
    friend void fun1(const Test& t); //声明为友元函数
public:
    Test(int n = 0)
        :mynum(n)
    {}

private:
    int mynum;
};

void fun1(const Test& t)
{
    cout << t.mynum << endl; //友元函数可以直接访问对象的内部私有和保护成员
}

void fun2(const Test& t)
{
    cout << t.mynum << endl; //这里会报错
}//其他函数只能访问公开成员

C++ [类和对象 - 下]

   

特性

  • 友元函数可访问类的私有和保护成员,但不是类的成员函数
  • 友元函数不能用const修饰
  • 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
  • 一个函数可以是多个类的友元函数
  • 友元函数的调用与普通函数的调用原理相同

友元函数特殊使用场景

 

自定义类型重载流提取和流插入运算符

问题:当我们尝试去重载operator<<,然后发现没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以要将operator<<重载成全局函数。但又会导致类外没办法访问成员,此时就需要友元来解决。operator>>同理。

//日期类重载流插入提取运算符 - 友元函数法
class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
	friend istream& operator>>(istream& _cin, Date& d);
public:
	Date(int year = 1970, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}

istream& operator>>(istream& _cin, Date& d)
{
	_cin >> d._year;
	_cin >> d._month;
	_cin >> d._day;
	return _cin;
}

友元类

使用 friend 修饰类并声明在其他类中可以成为该类的友元类!

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

class Time
{
	friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
public:
	Time(int hour = 0, int minute = 0, int second = 0)
		: _hour(hour)
		, _minute(minute)
		, _second(second)
	{}
private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	void SetTimeOfDate(int hour, int minute, int second)
	{
		// 直接访问时间类私有的成员变量
		_t._hour = hour;
		_t._minute = minute;
		_t._second = second;
	}
private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

特性

  • 友元关系是单向的,不具有交换性(比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行)
  • 友元关系不能传递
  • 如果C是B的友元, B是A的友元,则不能说明C时A的友元
  • 友元关系不能继承
  • 友元类可以在类定义的任何地方声明,不受类访问限定符限制

内部类


概述

如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。内部类就是外部类的友元类,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元

class A
{
public:
  class B //B称为A的内部类
  {
   private:
        int Bnum;
  }; 

private:
     int Anum;
};

这里B是A的内部类(友元类),A是B的外部类!B可以访问A类的所有成员,但是A不能访问B类的所有成员!


特性

  • 内部类可以定义在外部类的public、protected、private都是可以的
  • 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名
  • 外部类的字节大小与内部类没有任何关系,两者相互独立
  • 与友元类的区别:内部类能受到外类的访问限定符限制
  • 内部类可以访问外类中的成员,而外类无法访问内部类的成员

内部类是平时使用极少,一般用于隐藏类!


匿名对象


class Test
{
    Test(int n = 0)
    :num(n)
    {    
        cout<<"Test()"<<endl;
    }

    ~Test()
    {    
        cout<<"~Test()"<<endl;
    }
private
    int num;
};


int main()
{
    Test(); //构造匿名对象
    return 0;
}

C++ [类和对象 - 下]

通过 类名() 的方式可以构造匿名对象,匿名对象最大的特性就是生命周期只在一行,对于一些对象只用一次的情况,可以使用匿名对象优化性能。

    

匿名对象的生命周期在某些条件下会延长,例如被const引用变量引用后,其生命周期延长至函数执行结束!


编译器对于自定义类型的一些优化


编译器在实例化,传参和隐式类型转换时并非按正常的流程运行,而是进行了一些优化(简化了执行流程),从而提升执行效率!


//示例代码 - 接下来的测试以此类进行
class Test
{
public:
    Test(int n = 0) //构造函数
    :num(n)
    {
        cout<<"Test(int n = 0)"<<endl;
    }

    Test(const Test& t) //拷贝构造函数
    {
        num = t.num;
        cout<<"Test(const Test& t)"<<endl;
    }

    Test& operator=(const Test& t) //赋值重载函数
    {
        num = t.num;
        cout<<"operator="<<endl;
        return *this;
    }

private:
    int num;
};

隐式类型转换的优化 

  

int main()
{
    Test t = 10;
    return 0;
}

C++ [类和对象 - 下]

C++ [类和对象 - 下]

优化前:int类型转换为Test类型都临时对象,拷贝构造临时对象构造对象 t 

//相当于
//10 -> Test tmp(10) -> Test t(tmp)
// 先方式类型转换     再拷贝构造

优化后: 直接将10作为构造参数构造对象 t 

//相当于
Test t(10);

传参优化

    

void fun(Test t) {}

int main()
{
    fun(10);
    return 0;
}

C++ [类和对象 - 下]

优化前:int类型转换为Test类型(与以上隐式类型转换相同),然后 t 通过拷贝构造形成对象

//相当于
//10 -> Test tmp(10) -> Test t(tmp)
// 先方式类型转换     再拷贝构造

优化后:直接构造形成对象

这里与隐式类型转换的优化相似!


返回值优化

    

Test fun()
{
    return Test(10); //匿名对象
}

int main()
{    
    Test t = fun();
    return 0;
}

C++ [类和对象 - 下]

优化前:构造匿名对象,返回匿名对象的拷贝临时变量,将临时对象拷贝构造形成对象 t

优化后:通过返回的匿名对象,直接构造对象 t 


说明

  • 引用传参时,编译器无需优化,因为不会涉及拷贝构造
  • 实际编码时,如果能采用匿名构造,就用匿名构造,会加速编译器的优化
  • 接收参数时,如果分成两行(先定义、再接收),编译器无法优化,效率会降低

编译器会将不必要的 拷贝构造和构造 步骤去掉,优化为直接构造!

  

编译器只能在一行语句内进行优化,如果将这些语句拆分为多条语句,编译器则不会优化,因为编译器不能擅自主张。

//例如
int main()
{
    Test t;
    t = 10;
    return 0;
}

C++ [类和对象 - 下]


合理使用优化

  

因为编译器对这些情况有优化,所以我们使用以下技巧可以提高程序效率!

  • 接收返回值对象时,尽量拷贝构造方式接收,不要赋值接收
  • 函数返回时,尽量返回匿名对象
  • 函数参数尽量使用 const& 参数

关于对象的理解


现实生活中的实体计算机并不认识,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。比如想要让计算机认识洗衣机,就需要:

  1. 用户先要对现实中洗衣机实体进行抽象---即在人为思想层面对洗衣机进行认识,洗衣机有什么属性,有那些功能,即对洗衣机进行抽象认知的一个过程。
  2. 经过1之后,在人的头脑中已经对洗衣机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计算机识别人想象中的洗衣机,就需要人通过某种面相对象的语言(比如:C++、Java、Python等)将洗衣机用类来进行描述,并输入到计算机中
  3. 经过2之后,在计算机中就有了一个洗衣机类,但是洗衣机类只是站在计算机的角度对洗衣机对象进行描述的,通过洗衣机类,可以实例化出一个个具体的洗衣机对象,此时计算机才能洗衣机是什么东西。
  4. 用户就可以借助计算机中洗衣机对象,来模拟现实中的洗衣机实体了。

在类和对象阶段,大家一定要体会到,类是对某一类实体(对象)来进行描述的,描述该对象具有那些属性,那些方法,描述完成后就形成了一种新的自定义类型,才用该自定义类型就可以实例化具体的对象。

C++ [类和对象 - 下]


最后

<类和对象 - 下> 的知识介绍到这里就结束了!本篇介绍了类变量的定义在初始化列表以及初始化列表的合理使用,static成员的定义,友元概念和编译器的一些优化,相信这些细节的加持下,我们能加深对类和对象的理解,更加合理的使用类,类和对象的知识。类和对象的知识介绍到这里就结束了,希望小伙伴们都能理解!

本次 <C++类和对象 - 下> 就介绍到这里啦,希望能够尽可能帮助到大家。

如果文章中有瑕疵,还请各位大佬细心点评和留言,我将立即修补错误,谢谢!

C++ [类和对象 - 下]

🌟其他文章阅读推荐🌟

C++ <类和对象 - 中> -CSDN博客 

C++ <类和对象 - 上> -CSDN博客

C++入门知识 -CSDN博客

🌹欢迎读者多多浏览多多支持!🌹文章来源地址https://www.toymoban.com/news/detail-402521.html

到了这里,关于C++ [类和对象 - 下]的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】类和对象(四)

    前言:在类和对象中,我们走过了十分漫长的道路,今天我们将进一步学习类和对象,类和对象这块荆棘地很长,各位一起加油呀。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量C++学习 👈 💯代码仓库:卫卫周大胖的学习日记💫 💪关注博主和博主一起学习

    2024年02月19日
    浏览(34)
  • 【C++】:类和对象(1)

    朋友们、伙计们,我们又见面了,本期来给大家解读一下有关C++中类和对象的知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏: C语言:从入门到精通 数据结构专栏: 数据结构 个  人  主  页 : stackY、 目录 1.面向过程和面

    2024年02月08日
    浏览(37)
  • 【C++】类和对象(上)

    个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C++之路】 C语言是面向过程的,而C++是面向对象的,那面向过程和面向对象到底是什么呢? 我们拿一个非常典型的 外卖系统 来进行举例: 面向过程: 我们知道外面

    2024年02月02日
    浏览(45)
  • 【C++】类和对象(3)

    首先我们先回顾一下构造函数,对象的初始化由构造函数来完成,我们可以在构造函数的函数体内对对象的成员变量进行赋值,但这就有一个问题,如下: 答案:显然不是,因为变量只能定义一次。 也就是说,构造函数的函数体内部并不是初始化的地方(定义的地方),而

    2024年02月06日
    浏览(34)
  • 【C++】类和对象(下)

    在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值 ,而不能称作初始化。因为初始化只能

    2024年03月25日
    浏览(49)
  • 【C++】类和对象(一)

    C++对C语言的补充最重要的功能之一就是类和对象的引入,在学习完漫长的C语言,从这里就算是开始踏上了高级语言之路,C++的这门语言有太多细节了,所以也要花费更多的时间和更多的精力,去面对更多的困难,做好心里准备,学校杂七杂八的事情,想要让学习和生活上的

    2024年02月05日
    浏览(29)
  • C++类和对象(上)

    ✨Blog:🥰不会敲代码的小张:)🥰 🉑推荐专栏: C语言 🤪、 Cpp 😶‍🌫️、 数据结构初阶 💀 💽座右铭:“ 記住,每一天都是一個新的開始😁😁😁 ” 💀本章内容: 《C++类和对象(上)》的介绍✨ C语言是面向过程的,关注的是过程,分析出求解的步骤,通过函数逐步解

    2024年01月25日
    浏览(38)
  • C++类和对象练习

    要求: (1)包含成员变量 m_a(立方体边长)。 (2)包含函数 SetA(doublea)(设置立方体边长)、GetVolume()(计算体积)、GetArea()(计算表面积)。 (3)包含函数 Display(),用来输出计算的结果。 (4)设计测试用主函数 main(),用来测试 Box 类。 包括: (1)普通数据成员:姓

    2023年04月18日
    浏览(40)
  • 【C++】类和对象-友元

    不在类外定义成员函数:

    2024年02月15日
    浏览(39)
  • c++学习——类和对象

    类是自定义数据类型,是C语言的结构体进化而成的 对象是类实例化出的,用数据类型定义一个变量 C和C++中struct区别: C语言struct只有变量 C++语言struct既有变量,也有函数 1、为什么要有封装? 封装是把属性(变量)和方法(函数)封装到类内,然后给这些数据赋予权限,防

    2024年02月07日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包