c++

【C++基础进阶】class、struct、union

Posted by 卢小胖 on 2021-09-28
Estimated Reading Time 6 Minutes
Words 1.5k In Total
Viewed Times

类class

类是面向对象中的特性,在c中是没有类的概念。通常用class来表示,cpp中有抽象类,但是没有接口这种说法,cpp支持多继承。

一个普通的类:

class Fruit
{
private:

public:
Fruit();
~Fruit();
};

Fruit::Fruit()
{
}

Fruit::~Fruit()
{
}

构造函数和析构函数:

其中Fruit()表示构造函数,~Fruit()表示析构函数。构造函数用来创建对象,设置初始化参数。析构函数在对象销毁的时候执行。

修饰符:

  • private:表示私有成员,外部不可访问,只有自身类和友元函数可以访问。
  • public:表示公共成员,外部可以访问。
  • protected:表示保护成员,保护成员和私有成员相似,但是子类可以访问保护成员。

类中的成员函数:

我们在类中创建函数的时候,可以直接初始化,或者在类外部实现:

class Fruit
{
private:
int count;
public:
Fruit();
~Fruit();

void add(int i);

//直接初始化
int getCount(){
return count;
}
};

Fruit::Fruit()
{
cout << "create fruit" << endl;
}

Fruit::~Fruit()
{
cout <<"fruit deleted"<<endl;
}

//在类外部实现
void Fruit::add(int i){
count = count + i;
}

友元函数:

友元函数虽然可以在类中定义,但是它不属于类的成员函数,必须在类外部实现。它可以访问定义类中的private和protected成员。

友元类:友元类中的所有函数都是该类的友元。


#include <iostream>
using namespace std;

class Fruit
{
private:
int count = 0;
public:
Fruit();
~Fruit();

// friend void printF(Fruit ft);
friend void printF(Fruit &ft);
};

// void printF(Fruit ft){
// cout << ft.count <<endl;
// }

void printF(Fruit &ft){
cout << ft.count <<endl;
}

int main(){

Fruit fruit;

printF(fruit);

return 0;
}

this指针: 类的成员函数中都可以用this指针来访问类成员,this指针是const指针,不可修改。

虚函数、纯虚函数、抽象类:

虚函数: 使用关键字virtual修饰

virtual void fuck2(){
cout <<"fuck 2"<<endl;
}

虚函数表示被子类重写的时候,调用子类的函数而不是父类的此函数

纯虚函数:空的虚函数

virtual void fuck() = 0;

抽象类: 只要类中有纯虚函数就代表是抽象类

抽象类是被实体化的,必须通过子类创建。

class Fruit
{
private:
public:
Fruit();
~Fruit();
virtual void fuck() = 0;

void fuck1(){
cout <<"fuck 1"<<endl;
}

virtual void fuck2(){
cout <<"fuck 2"<<endl;
}
};

继承: 注意继承需使用public修饰,

class Apple: public Fruit
{
private:

public:
Apple();
~Apple();

void fuck(){
cout << "fuck apple"<<endl;
};

void fuck2(){
cout << "fuck apple 22"<<endl;
};

};

调用看输出结果:

Apple apple;
apple.fuck();
apple.fuck1();
apple.fuck2();

输出:

fuck apple
fuck 1
fuck apple 22
  • fuck()是纯虚函数,调用的是子类
  • fuck1()调用的是父类的方法
  • fuck2()因为是虚函数,又被子类重写了,所以调用的是子类。如果子类不重写虚函数,还是会调用父类的。

多继承如下:

class Apple: public Fruit, public Orange{

}

结构体struct

cpp可以用struct来创建自定义数据结构,相当于java中的bean类

创建一个基本的结构体:

struct Book
{
string name;
int id;
long int ISBN;
};

可以在} ;之间创建一个或多个结构体对象:

struct Book
{
string name;
int id;
long int ISBN;
}book1,book2;

数据局初始化:

<!--直接赋值:-->
book1.name = "C++ programing";

<!--或者创建的时候初始化:-->
Book book3{
"Android++",
1,
21321231
};

cout<<book3.id<<endl;
cout<<book3.name<<endl;
cout<<book3.ISBN<<endl;

使用类型别名:

typedef struct{
int id;
string name;
}Ebook;

我感觉是无用的语法糖。

结构体指针:

Ebook ebook{
2,"啊哈哈哈"
};

Ebook *ptr_book;
ptr_book = &ebook;

cout<< ptr_book->id <<endl;
cout<< ptr_book->name <<endl;

和普通指针没啥区别

结构体和class的区别在哪里?

  • 总的来说,struct 更适合看成是一个数据结构的实现体,class 更适合看成是一个对象的实现体。
  • 默认的继承访问权限:struct 默认是public的,class默认是private的。

c和cpp中的struct有什么不同?

  • c中只能作为数据的结构体,不能有函数,cpp中struct是可以有函数的
  • c中没有修饰符,cpp中结构体可以有public、protected、private修饰符
  • c中创建结构体必须加struct前缀,比如:struct Book book,真是book思议
  • c中没有继承概念,cpp中struct可以继承

演示:

struct TBook : public Book
{
private:
int ids = 1232342;
public:
string names;
long int TTT;
void printBook(TBook *book);
}tbook;

void TBook::printBook(TBook *book){
cout<<book->ids<<endl;
cout<<book->names<<endl;
cout<<book->TTT<<endl;

cout<<book->name<<endl;
}

执行:

tbook.name = "C++";
tbook.names = "Android++";
tbook.TTT = 1213;

tbook.printBook(&tbook);

输出结果:

1232342
Android++
1213
C++

共用体union

共用体类似于结构体,但是只会同时存在一个数据成员,在一个成员被赋值后,其他成员值将会丢失。

union ONE
{
int i;
float j;
double ids[10];
};

int main(){

ONE one;
one.i = 123;
cout << one.i <<endl;

one.j = 1.0f;
cout << one.i <<endl; //one.i将会丢失
cout << one.j <<endl;

return 0;
}

共用体特点:

  • 默认访问控制符为 public
  • 可以含有构造函数、析构函数
  • 不能含有引用类型的成员
  • 不能继承自其他类,不能作为基类
  • 不能含有虚函数
  • 匿名 union 在定义所在作用域可直接访问 union 成员
  • 匿名 union 不能包含 protected 成员或 private 成员
  • 全局匿名联合必须是静态(static)的

配合结构体使用:

struct PEOPLE
{
string name;
union TEST
{
int id;
float id_f;
} test;

};