C++中的面向对象

俗话说,面向对象是C++区别于C的基础和核心。本文将简要介绍C++的类与对象。

访问控制属性

publicprivateprotected
可以类外访问只能由类成员和友元访问可以被派生类对象访问
一部分函数可以是public的数据尽量定义成private的

类的实现

  1. 类的成员函数描述的是类的行为或操作
  2. 函数的原型声明要在类的主体中,而函数的实现一般写在类声明之外
  3. 定义类的成员函数:
返回值类型 类名::成员函数名(参数表){
    函数体
}

4. 成员函数可以访问本类的任意成员。这表明成员函数可以直接调用类里面已经定义的所有成员,无论是public, private还是protected.

面向对象一般写三个文件,一个是定义类成员函数的头文件(.h),一个是实现函数的.cpp文件,一个是主程序文件。下面举个例子。

这是clock.h中的内容:

//clock.h
class Clock{
    public:
        void setTime(int NHour, int NMinute, int NSecond);//参数可以带默认值,但注意要在右边
        void showTime();
    private:
        int Hour;
        int Minute;
        int Second;
};
//clock.cpp
#include "Clock.h"
void Clock::setTime(int NHour, int NMinute, int Nsecond){//setTime()函数
    Hour = NHour;
    Minute = NMinute;
    Second  = NSecond;
void Clock::showTime(){
    cout << Hour << ":" << Minute << ":" << Second << endl;
}

对象

定义对象和定义一般变量并无不同,为:<类名> <对象名>;例如:

#include "Clock.h"
#include 
using namespace std;
int main(){
    Clock myclock;
    myclock.setTime(12, 5, 0);
    myclock.showTime();
}

要注意的是,类中的变量一定是不能有初始值的。因为类是一个抽象的概念,不占用空间。

实例化之后,这个实例的变量会被分配空间,但是函数是不占用空间的。

类的作用域

类作用域是指类定义和相应的成员函数定义的范围,通俗地称为类的内部。

c++认为一个类的全部成员都是一个整体的相关部分。

一个类的所有成员位于这个类的作用域内,在该范围内,一个类的成员函数对本类的其它成员拥有无限制的访问权。

类的可见性

  1. 类名实际上是个类型名允许与其它变量、函数同名;
  2. 在类的内部,与类或类的成员同名的全局变量名和函数名将不可见。

构造函数

定义构造函数的一般形式为:

class 类名{
    public:
    类名(形参表);
}
类名::类名(形参表){//构造函数不允许返回值
    函数体;
}

}

构造函数的名字与类名是完全相同的,并且不会返回任何类型,也不会返回void。构造函数可用于为某些成员变量设置初始值。构造函数必须是公有的。

构造函数可以带默认形参,也可以重载。

每一个类都会存在构造函数,如果用户没有写,编译器会自己创造一个;如果写了就不会重新创造了。

实例:构造函数:

class Clock{
    public:
        Clock(int H, int M, int S);//构造函数
        void setTime(int NHour, int NMinute, int NSecond);
        void ShowTime();
    private:
        int Hour;
        int Minute;
        int Second;
};
Clock::Clock(int H, int M, int S){
Hour = H;
Minute = M;
Second = S;
}

//主程序中:
Clock myClock(12, 0, 1);
myClock.showTime();//正确,实例化中调用构造函数的形参

Clock b;//错误

构造函数的重载:

class Tdate{
    public:
        Tdate();
        Tdate(int d);
        Tdate(int m, int d);
        Tdate(int y, int m, int d);
    private:
        int month;
        int day;
        int year;
}

上述示例可以在传入参数个数不同的情况下重载不同的函数。

复制构造函数

复制构造函数的形参是类的对象的引用

Clock(const Clock &a){......}

复制构造函数与原来的构造函数实现了构造函数的重载

自动生成:如果在类定义的时候没有定义复制构造函数,编译器会生成默认的构造函数

何时会执行复制构造函数:

  1. 通过“=”复制对象时
  2. 对象作为函数的参数,函数调用时
  3. 函数返回对象时

复制构造函数是否可有可无?

-有些情况下可以不写,此时称为浅拷贝;

-有些情况必须写,此时称为深拷贝。

类中如果含有指针成员,执行默认复制构造函数时(浅拷贝):

-会将一个原对象的指针成员复制到新对象的指针成员;

-若指针成员指向堆内存,在原对象生存期结束时,析构函数将堆内存释放,则新对象的指针成员会变为悬挂指针,新对象生存期结束时析构函数会出错。

通常来说,复制构造函数的参数是引用名。

析构函数

析构函数用于在对象生存期结束后释放掉对象所占的内存空间。

访问属性:公有成员函数

参数名:在类名前加“~”构成

无参数、无返回值、不能重载(因为没有参数)

对象也可以作为返回对象和传递参数

student f(student s){
    函数体
}

传递的方法是值传递。

下面为一个例子:

class Tdate{
    public:
        void Tdate(int,int,int); //构造函数,实参传递给形参自动调用复制构造函数(可带默认值)
        void Print();
    private:
        int month;
        int day;
        int year;
};
void someFunction(Tdate someday){
    someday.print();
}
int main(){
    Tdate s(2003, 15, 2);
    someFunction(s);
    ........
}

return返回对象时自动执行复制构造函数。

类类型的指针及引用可以作为函数的参数及返回值。由于传递的是指针,不会执行复制构造函数。

Tdate &someFunc(Tdate &someday){ //这里的&表示引用运算符。
    return someday;
}
int main(){
    Tdate s(2023,15,2);
    Tdate t = someFunc(s);
}

Tdate *someFunc(Tdate *someday){
    return someday;
}
int main(){
    Tdate s(2003, 15, 2);
    Tdate t = *someFunc(&s);//对于指针变量,传入时要取地址;*表示取地址的值。赋值给t的时候会调用复制构造函数。
}

对象指针和堆对象

使用对象指针访问对象成员,使用->运算符。语法形式为:对象指针名->公有成员。

class Clock{
public:
    Clock(int H, int M, int S);
    void setTime(int H, int M, int S);
    void showTime();
private:
    int Hour;
    int Min;
    int Sec;
}
int main(){
    Clock* pmyclock = new Clock;//在堆区分配一个Clock的存储空间
    pmyclock->setTime(12,5,0);
    pmyclock->showTime();
    delete pmyclock;
}

this指针

在类的外部访问类的成员必须要通过对象来调用。

在成员函数内部,访问数据成员或者成员函数时并没有看到这些成员属于哪个对象。

在 C++ 中,this 指针是一个特殊的指针,它指向当前对象的实例。

在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。

this是一个隐藏的指针,可以在类的成员函数中使用,它可以用来指向调用对象。

当一个对象的成员函数被调用时,编译器会隐式地传递该对象的地址作为 this 指针。

友元函数没有 this 指针,因为友元不是类的成员,只有成员函数才有 this 指针。

class Clock{
public:
    Clock(int H, int M, int S);
    void setTime(int H, int M, int S);
    void showTime();
private:
    int Hour;
    int Min;
    int Sec;
}
void Clock::setTime(int H, int M, int S){
    this->Hour = H;
    this->Min = M;
    this->Sec = S;
}
//在调用参数时,我们实际上省去了一个this指针

内部类和命名空间

把一个类写在另一个类的内部,就称之为内部类。

内部类和普通类在使用上几乎无区别。

外部类不能自由访问内部类,内部类不能访问外部类。

内部类主要是为了避免类名的冲突。

class AAA{
    public:
        class inner{
    
    };

};

命名空间是解决名字冲突的终极方案。只要类名在一个命名空间中唯一就好了。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇