第7章 类

  • 定义在类内部的函数是隐试的inline函数
  • std::string isbn() const { return bookNo;}
    这里的const实在修改隐式this指针的类型

练习 7.4:编写一个名为Person的类。使其表示人员的姓名和住址。使用string对象存放这些元素,接下来的练习将不断充实这个类的其他特征

#include 
#include 

using namespace std;

struct Person
{
    string getName() const {return name;} 
//name定义在getName之后,依旧可以使用name。因为会首先编译成员声明。然后才轮到成员函数体
    string getAddress() const { return address;}
    string name;
    string address;
};

练习7.9:继续添加读取和打印的Person对象操作

#include 
#include 

using namespace std;

struct Person
{
    string getName() const {return name;}
    string getAddress() const { return address;}
    string name;
    string address;
};

std::istream & read(std::istream & is, Person & item)
{
    is >> item.name >> item.address;
    return is;
}

std::ostream & print(std::ostream & os, const Person & item)
{
    os << item.name << " " << item.address << " ";
    return os;
}
  • 当你定义了一个构造函数后。默认的构造函数便不会在执行
#include 
#include 

using namespace std;

struct Person
{
    // Person() = default;   //这里
    Person(const string n, const string a) : name(n), address(a) { }
    string getName() const {return name;}
    string getAddress() const { return address;}
    string name;
    string address;
};

std::istream & read(std::istream & is, Person & item)
{
    is >> item.name >> item.address;
    return is;
}

std::ostream & print(std::ostream & os, const Person & item)
{
    os << item.name << " " << item.address << " ";
    return os;
}

int main()
{
    Person x;   //这里
    //上面那一行会报错,因为没有办法初始化,所以需要一个默认的构造函数Person() = default;
    cout << x.name;
}

struct 和 class

  • struct默认是public
  • class默认是private

7.16:在累的定义中对于访问说明符出现的位置和次数有限定吗?

  • 一般来说没有

练习7.17: 使用class和struct有什么区别

  • 唯一的区别就是默认的访问权限

练习7.18:封装是何含义?它有什么用处?

  • 定义一系列的接口,对用户隐藏实现的细节。用户只要去调用接口就行

友元
友元声明只能出现在类定义内部,友元不是类成员也不受它所在区域访问控制级别的约束。

练习7.22:修改你的Person类使其隐藏实现的细节

#include 
#include 

using namespace std;

struct Person
{
friend std::istream & read(std::istream & is, Person & item);
friend std::ostream & print(std::ostream & os, const Person & item);

    string getName() const {return name;}
    string getAddress() const { return address;}
    Person() = default;
    Person(const string n, const string a) : name(n), address(a) { }
private:
    string name = "";
    string address = "";
};

std::istream & read(std::istream & is, Person & item)
{
    is >> item.name >> item.address;
    return is;
}

std::ostream & print(std::ostream & os, const Person & item)
{
    os << item.name << " " << item.address << " ";
    return os;
}

友元声明
在一个类允许另一个类访问此类包括私有成员在内的所有成员

struct X
{
    friend void f();   //友元函数可以定义在类的内部
    X() {f();}      //错误:f还没有被声明
    void g();       
    void h();
};
void X::g() { return f();}  //错误:f还没有被声明
void f();                   //声明f
void X::h() { return f();}  //正确f声明了


构造函数

Sales_data::Sales_data(const string &s, unsigned cnt, double price)
{
    bookNo = s;
    units_sold = cnt;
    revenue = cnt * price;
    /*这种写法不好,比较草率,属于先初始化。然后再去赋值*/
}

练习7.36: 下面的初始值是错误的,请找出问题所在并尝试修复它。

struct X
{
          X (int i, int j): base(i), rem(base % j) { }
          int rem, base;
顺序问题。初始化的顺序按照出现先后。先会出事rem发现base没有
}

编译器会进行隐式的类类型转换将string变成sales_data不过,可以用explicit来阻止。不是绝对可以使用显示的强转

练习7.49: 对于combine函数的三种不同声明,当我们调用i.combine(s)时分别发生什么情况?其中i时Sales_data,而s时一个string对象

a) Sales_data &combine(Sales_data);//正常执行
b)Sales_data &combine(Sales_data&);//执行失败引用想要引用常量必须const
c)sales_data &combine(const Sales_data&) const;//可以,不过里面会有变量的修改所以还是失败

类的静态成员

  1. 使用static声明,静态成员可以是public或private
  2. 类的静态成员函数,可以在外部定义。不过在外部定义不要加static
  3. 类内初始化。必须是字面值类型constexpr。初始值不需是常量表达式。
  4. 即使在类部初始化了也应该在外部定义一下
#include 
#include 

using namespace std;

class Account
{
public:
    void calculate() { amount += amount * intersetRate;}
    static double rate() { return intersetRate; }
    static void rate(double);

private:
    std::string owner;
    double amount;
    static double intersetRate;
    static double initRate() { return 5;};
};

double Account::intersetRate = initRate(); //在定义一个intersetRate对象,是类的静态成员。
                        //从类名开始,这条定义语句的剩余部分都位于作用域之类了。可以直接使用私有initRate。初始化

int main(void)
{
    double r;
    r = Account::rate();
    cout << r;
    Account::rate(10);
    cout << Account::rate();
    return 0;
}

void Account::rate(double newRate)
{
    intersetRate = newRate;
}

你可能感兴趣的:(第7章 类)