欢迎光临散文网 会员登陆 & 注册

C++类基础

2023-09-06 20:50 作者:虚云幻仙  | 我要投稿

#include <iostream>

using namespace std;

class Stack //类,面向对象,类名为Stack

{

    public: //以下内容均为public,可供类外调用

     Stack(); //类的构造器constructor,在每次声明类的对象时执行初始化操作

     Stack(const int); //构造器的格式为 类名(参数可选) ,构造器没有返回值不写void,多个构造器构成重载,注意避免重载和默认参数二义性

     ~Stack(); //析构器destructor,在对象释放时执行,格式为 ~类名() ,无参无返回不写void

     //构造器和析构器在没有手动定义的情况下会默认生成无参空函数

     bool push(char); //在类中可以写完整的函数定义,如果分成头文件和.cpp两部分应在头文件中只写函数声明

     bool isFull() //所有在类声明中定义的方法都将自动内联

     {

         return top >= size; //调用的top、size均为类的成员/字段,在类中可直接调用

     }

     bool isempty()

     {

         return top <= 0;

     }

     char pop(); //类的普通函数/成员函数需声明返回值类型

    private: //以下内容均为private私有,在类外无法直接调用

     char* arr; //成员arr,指针用于指向数组

     int size=1024; //默认数组的大小,c++11类内初始化(之前版本不允许)

     int top=0; //栈顶,默认没有项

}; //头文件截止


//.cpp文件

Stack::Stack() //Stack类的名称空间,不会和文件中全局函数Stack()冲突(如果有的话)

{

    arr = new char[size]; //构造器中创建数组内存块

}

Stack::Stack(const int s) //接收一个参数,用于指定栈的大小

{

     size = s>0?s:size; //防御性代码

     arr = new char[size]; //类的函数中可以直接使用类的成员,即使在类声明外

     //函数中没有打算改变s的值,所以声明为const,尽量使用const提高函数的兼容性/避免用变量接收调用时传入的常量

}

//错误: Stack::size = 20; 在类外只能访问类的public内容,在public的函数中可以访问private成员(就像上面的构造函数中访问size)

Stack::~Stack()

{

    delete[]arr; //释放构造阶段分配的空间

}

bool Stack::push(char ch) //向栈中压入项

{

     if (isFull())

          return false;

     arr[top++] = ch;

     return true;

}

char Stack::pop()

{

     if (isempty())

          return NULL;

     return arr[--top];

}

//如果在类外写作inline char Stack::pop() {}将函数定义为内联函数,类声明中的函数原型不需要写inline,所以将函数定义写在类声明中等价于在类外写inline定义


int mainclass1()

{

     Stack sta; //创建对象,该对象大小为成员大小的总和(有可能因为对齐要求补一些空位),即char* arr 8/int size 4/int top 4总共16,不包含arr指向的动态内存,也不包含函数

     cout << sizeof(sta) << endl;

     sta.push('c');

     cout<<sta.pop()<<endl;

     Stack sta2(16); //调用有参构造器

     char ch = 'a';

     while (sta2.push(ch++))

     {

         continue;

     }

     while (!sta2.isempty())

     {

          cout << sta2.pop();

     }

     //sta和sta2均为自动变量,所在块结束时会释放,自动调用~Stack()析构器

     Stack sta4(16), sta5(32), sta6; //前两个使用有参构造器,最后一个使用无参构造器

     Stack* ps = new Stack; //ps是指针,占一个指针的大小8字节,指向new动态分配的内存空间,new Stack调用无参构造器,将对象(16字节)的地址传给ps

     delete ps; //动态变量ps需要手动释放,调用delete释放ps指向的空间时会先执行对象的析构器

     Stack* ps2 = new Stack(16); //调用有参构造器

     delete ps2;

     Stack sta3 = Stack(16); //等价于Stack sta3(16); 创建一个对象后标识为sta3,实际经过编译后标识符sta3不存在,直接使用sta3的地址

     //如果类中没有声明成员,则类的大小为1(占位用),即便没有成员、没有手动声明构造器,创建对象时依然会执行默认生成的构造器,即创建对象一定会进行初始化,即便初始化操作没有改变任何东西/没有做任何事

     //Stack c;只要创建对象,无论这语句写在哪里,都会执行初始化

     return 0;

}

class Stack2

{

     //不写访问控制默认private

     int size_; //可以采用p_size或者size_表示数据成员

    public:

     Stack2(int size) //形参正常书写便于用户理解

     {

         size_ = size; //size_对应size便于维护,且用户无法看到私有的size_成员,只能看到构造器中形参名size

     }

};

class claSt1

{

     int i;

     char c;

     double d;

};

void mainclaSt1()

{

    cout << sizeof(claSt1); //int占4字节char占1字节,但double对齐要求为8所以char之后空出3字节,实际大小16字节

}


C++类基础的评论 (共 条)

分享到微博请遵守国家法律