C++ Primer5 第七章课后题 练习笔记

本文深入探讨C++中class与struct的区别,拷贝与赋值的默认行为,不完全类型的概念,以及静态成员的特性与优势。同时,介绍了聚合类的定义与使用,以及成员初始化的顺序规则。

关于class和struct

唯一区别:默认访问权限不同。类可以在它的第一个访问说明符之前,定义成员,对这种成员的访问依赖于类的定义方式。对于struct关键字,定义在第一个访问说明符之前的成员是public的,class则相反。

关于默认的拷贝和赋值

含有指针数据成员的类一般不宜使用默认的拷贝和赋值操作,如果类的数据成员都是内置类型,则不受干扰。

Screen类练习

#include<iostream>
#include<string>
using namespace std;

class Screen
{
private:
    unsigned height = 0, width = 0;
    unsigned cursor = 0;
    string contents;
public:
    Screen() = default;     //默认构造函数
    Screen(unsigned ht, unsigned wd) : height(ht), width(wd),
        contents(ht * wd, ' ') { }
    Screen(unsigned ht, unsigned wd, char c)
        : height(ht), width(wd), contents(ht * wd, c) { }
public:
    Screen& move(unsigned r, unsigned c)
    {
        cursor = r * width + c;
        return *this;
    }
    Screen& set(char ch)
    {
        contents[ cursor ] = ch;
        return *this;
    }
    Screen& set(unsigned r, unsigned c, char ch)
    {
        contents[ r * width + c] = ch;
        return *this;
    }
    Screen& display()
    {
        cout << contents;
        return *this;
    }
};

int main()
{
    Screen myScreen(5, 5, 'X');
    myScreen.move(4,0).set("#").display();
    cout << "\n";
    myScreen.display();
    cout << "\n";
    return 0;
}

move、set和display函数的返回类型是Screen&,返回值是引用,表明函数返回的是对象本身,一系列操作在同一个对象上执行;函数的返回值如果不是引用,表明函数返回的是对象的副本,则上述各函数只返回一个临时副本,不会改变myScreen的值。

关于不完全类型

不完全类型:声明未定义。我们可以定义指向不完全类型的指针,但是不能创建不完全类型的对象。

关于类成员声明的名字查找和成员定义中名字的查找

typedef string Type;        //声明类型别名Type表示string
Type initVal();             //声明函数initVal,返回类型是Type
class Exercise{             //定义一个新类Exercise
public:
    typedef double Type;    //在内层作用域重新声明类型别名Type表示double
    Type setVal(Type);      //声明函数setVal,参数和返回值的类型都是Type
    Type iniVal();          //在内层作用域重新声明函数initVal,返回类型是Type
private:
    int val;                //声明私有数据成员
};
//定义函数setVal,此时的Type显然是外层作用域的
Type Exercise::setVal(Type parm){ //形参Type用的是类内定义的别名,double
    val = parm + initVal();     //此时使用的是类内的initVal函数
    return val;
}
//上述程序存在问题,返回值类型不匹配
//修改
Exercise::Type Exercise::setVal(Type parm){ //形参Type用的是类内定义的别名,double
    val = parm + initVal();     //此时使用的是类内的initVal函数
    return val;
}

关于使用构造函数初始值列表时成员的初始化顺序

初始化顺序只与数据成员在类中出现的次序有关,而与初始值列表的顺序无关。

struct X{
    X (int i, int j): base(i), rem(base % j) { }
    int rem,base;  //错误,应该改为  int base,rem;
}

提供cin作为接受istream&参数的构造函数的默认实参,构造函数声明

Sales_data(std::istream &is=std::cin) { is >> *this; }

关于聚合类

聚合类使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。

条件:(1)所有成员都是public(2)没有定义任何构造函数(3)没有类内初始值(4)没有基类,也没有virtual函数

constexpr函数只能包含return语句,不允许执行其他任务。

聚合类即是字面值常量类

什么是类的静态成员?它有何优点?静态成员与普通成员有何区别?

静态成员是指声明语句之前带有关键字static的类成员,静态成员不是任意单独对象的组成部分,而是由该类的全体对象所共享。

静态成员的优点包括:作用域位于类的范围之内,避免与其他类的成员或者全局作用域的名字起冲突;可以是私有成员,而全局对象不可以;通过阅读程序可以非常容易的看出静态成员与特定类关联,使得程序的含义清晰明了。

静态成员和普通成员的区别主要体现在普通成员与类的对象关联,是某个具体对象的组成部分;而静态成员不从属于任何具体的对象,它由该类的所有对象共享。还有,静态成员可以作为默认实参,而普通数据成员不能作为默认实参。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值