类的定义

类的定义

6. 类定义的语法格式

  • 在定义数据成员时不能直接进行初始化,要为数据成员提供初始值应该放在构造函数中。
  • 类定义的末尾应添加分号。

7. C++ 中类成员访问权限有哪几种,简述其作用?

  • private:类中的 private 成员只能够在本类中或者友元类中进行访问。子
    类或者外界是无法访问私有成员的。
  • protected:类中的 protected 成员只允许本类或者子类中进行访问。外界
    无法访问 protected 成员。在定义类时,如果希望该成员能够被子类继承,但是不被外界访问,可以定义 protected 成员。
  • public:类中的 public 成员能够在本类、子类和外界中都能够进行访问。
    通常,类中向用户提供的服务设计为 public 成员。

8. 如何在类中定义常量成员并为其初始化?

要为常量初始化,需要在类的构造函数的初始化部分进行,也就是在构
造函数的函数体前使用 “:” 定义初始化区域,在该区域进行初始化。

class CBook
{
public:
    const double m_Price; //定义常量成员
    CBook() :m_Price(89.8) //为常量进行初始化
    {
    }
};

9. 由析构函数引起的递归调用

析构函数由系统自动调用。有两种情况将导致析构函数被调用。一是对
象的作用域消失,二是使用 delete 运算符释放对象。

class CNode
{
public:
    CNode* pNext;
    CNode() //构造函数
    {
        pNext = this;
    }
    ~CNode() //析构函数
    {
        if(pNext!=NULL)
        {
            delete pNext;
            pNext = NULL;
        }
    }
};

上面代码出现了递归调用。在析构函数中执行 “delete pNext;” 语句时导致递归。因为在析构函数中使用 delete 运算符释放自身,这将导致再次调用析构函数,致使析构函数出现递归。

10. 在 C++ 中如何定义内联成员函数

  • 在定义成员函数时使用inline 关键字。
class CBook
{
private:
      double m_Price;
public:
      inline void SetPrice(double Price); //使用 inline 关键字定义内联函数
      CBook()
      {
      }
};
void CBook::SetPrice(double Price)
{
      m_Price = Price;
}
  • 在定义成员函数时直接写出函数体。
class CBook
{
private:
      double m_Price;
public:
      void SetPrice(double Price) //在定义成员函数时直接给出函数体,自动为内联函数
      {
           m_Price = Price;
      }
      CBook()
      {
      }
};

11. 构造函数与普通函数在形式上有何不同?

  • 名字与类相同,无返回值
  • 无参数,或若干参数,无参数的构造函数叫默认构造函数;如果不提供构造函数,则编译器提供默认构造函数,如提供了任何形式的构造函数,编译器不会提供默认构造函数

12. 如何定义两个类互为成员的情况?

classA
{
private:
    B m_B;
};
class B
{
private:
    Am_A;
};

不用进行编译,就可以预知存在错误。因为在类 A 之前,没有发现类 B 的定义,直接使用了类 B。为了解决这个矛盾,需要在类 A 上方前导声明类 B。但是这还不能完全解决问题。因为前导声明只是声明一个类,而没有类的定义,编译器在编译类 A 时需要实例化类 B,但是却没有发现类 B 的定义,而只是发现了类 B 的声明。解决方式是在类 A 中,将 m_B 对象修改为指针类型。

class B; //前导声明类 B
classA
{
private:
    B *m_B; //定义类 B 的指针类型
};
class B
{
private:
    Am_A;
};

13. 已知 String 类的定义, 请添加实现部分。

class String
{
public:
    String(const char *str = NULL); //通用构造函数
    String(const String &another); //拷贝构造函数
    ~ String(); //析构函数
    String &operator =(const String &rhs); //赋值函数
private:
    char *m_data; //用于保存字符串
};

在定义一个类时如果没有指定这些函数,编译器会为其提供这 4 个特殊的函数。除了构造函数之外,其余 3 个函数都具有特定的函数原型。例如,析构函数的名称为 “~” 加上类名,没有参数和返回值。拷贝构造函数与类名相同,参数为一个常量引用类型参数。赋值函数参数为常量引用类型,返回值为类引用类型。

构造函数用于创建类对象。析构函数用于释放对象。拷贝构造函数用于
在类对象作为函数参数或函数返回值时被调用,用于临时构建对象。赋值函数用于实现对象间的直接赋值。

参考代码如下:

String::String(const char *str) //实现构造函数
{
    if ( str == NULL ) //判断参数是否为空
    {
        m_data = new char[1] ;
        m_data[0] = '\0' ;
    }
    else
    {
        m_data = new char[strlen(str) + 1];
        strcpy(m_data, str);
    }
}
String::String(const String &another) //实现拷贝构造函数
{
    m_data = new char[strlen(another.m_data) + 1];
    strcpy(m_data, another.m_data);
}
String& String::operator =(const String &rhs) //实现赋值函数
{
    if ( this == &rhs)
        return *this ;
    delete []m_data; //删除原来的数据,新开一块内存
    m_data = new char[strlen(rhs.m_data) + 1];
    strcpy(m_data,rhs.m_data);
    return *this ;
}
String::~String() //实现析构函数
{
    delete []m_data ;
}

14. 在定义类的成员函数时使用 mutable 关键字的作用是什么?

在定义类的方法时,如果在方法的末尾使用 const 关键字,表示该方法为 const 方法,此时在方法中不允许修改对象的信息。例如,下面的代码将出现编译错误。

class CStudent
{
private:
    intAge;
    int Weight;
public:
    void SetAge(intAge);
    int GetAge()const; //定义 const 方法
};
void CStudent::SetAge(intAge)
{
    this->Age =Age; //通过 this 指针来访问成员 Age
}
int CStudent::GetAge()const
{
    Weight = 10; //此处将出现编译错误
    returnAge;
}

上述代码在 const 方法中修改 Weight 成员导致的语法错误。为了能够在 const 方法中修改对象的成员信息,可以在成员前使用 mutable 关键字。例如,下面的代码是完全合法的。

class CStudent
{
private:
    intAge;
    mutable int Weight;
public:
    void SetAge(intAge);
    int GetAge() const ;
};
void CStudent::SetAge(intAge)
{
    this->Age =Age; //通过 this 指针来访问成员 Age
}
int CStudent::GetAge() const //实现 const 方法
{
    Weight = 10; //在 const 方法中为数据成员赋值
    return Age;
}

当需要在 const 方法中修改对象的数据成员时,可以在数据成员前使用 mutable 关键字,防止出现编译错误。

参考资料:
C++继承权限和继承方式

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 本文博客园地址:http://www.cnblogs.com/xiongxuanwen/p/4290086.htm...
    先之阅读 829评论 0 5
  • C++文件 例:从文件income. in中读入收入直到文件结束,并将收入和税金输出到文件tax. out。 检查...
    SeanC52111阅读 2,751评论 0 3
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,504评论 1 51
  • 一个博客,这个博客记录了他读这本书的笔记,总结得不错。《深度探索C++对象模型》笔记汇总 1. C++对象模型与内...
    Mr希灵阅读 5,564评论 0 13
  • 命令行执行多行存储过程DELIMITER //CREATE DEFINER=wxpaybase@% PROCEDU...
    ilkkzm阅读 294评论 0 0