C++自修入門實境秀、C++ Primer 5版研讀秀 46/ ~v7 類別 7.3. Additional Class Features-7....





7.3.3. Class Types

7.3.3類別型別

類別和型別的關係

Every class defines a unique type. Two different classes define two different types even if they define the same members.

只要不是一個類別,就是不同型別

頁278

練習7.27

10:48

1:21:50

Screen.h:

#pragma once

#ifndef Screen_H

#define Screen_H

#include<string>

#include<iostream>

using namespace std;

class Screen

{

public:

typedef string::size_type pos;

Screen() = default;

Screen(pos w,pos h,char c ) :w(w),h(h),contents(h*w,c){}

//Screen(pos w, pos h, char c) :w(w), h(h), contents{ c }{}//字元作為字串型別的初始器,原來是用{}

Screen(pos w,pos h,string s ) :w(w),h(h),contents(s){}

Screen(pos w,pos h,pos ctrBlanks ) :w(w),h(h),contents(ctrBlanks,' '){}



inline char get() { if(curser<contents.size()) return contents[curser]; }

string get(pos startposition,pos length) const; //不能用inline

void some_member() const;



Screen& set(char);//之所以要傳回對Screen的參考,是為了set move display等方法可以連動地用

Screen& set(pos,pos,char);

Screen& move(pos,pos);

Screen& display(ostream& os) { do_display(os); return *this; }

const Screen& display(ostream& os)const { do_display(os); return *this; }

private:

mutable size_t access_ctr=0; // may change even in a const object

// other members as before

pos curser = 0;

pos w = 0, h = 0;

string contents;

void do_display(ostream& os)const { os << contents; }

};



#endif // !Screen_H



Screen.cpp:

#include "Screen.h"



string Screen::get(pos startPos, pos length)const //不能用inline

{

pos x = startPos + length;

string s;

if (x < contents.size())

{

for (size_t i = startPos; i < x; i++)

{

s.push_back(contents[x]);

}

return s;

}

return "";

}

inline

void Screen::some_member() const

{

++access_ctr; // keep a count of the calls to any member function

// whatever other work this member needs to do

}



//inline

Screen& Screen::set(char c)

{

if (curser < contents.size())

{

contents[curser] = c; return *this;// TODO: insert return statement here

}

else

{

cout << "curser位置有誤!" << endl;

return *this;

}

}



inline //set move 3式中只有此式可以inline

Screen& Screen::set(pos r, pos col, char ch)

{

contents[r * w + col] = ch; return *this; // TODO: insert return statement here

}

//inline

Screen& Screen::move(pos r, pos c)

{

pos row = r * w;

curser = row + c; return *this;

}



Run: #include "Screen.h"

#include <iostream>

using namespace std;

int main() {

Screen myScreen(5, 5, 'X'); const Screen myConstScreen(10, 10, 'c');

myScreen.move(4, 0).set('#').display(cout);

cout << "\n";

myScreen.display(cout);

cout << "\n";

myConstScreen.display(cout);

cout << "\n";

}

原來用建構器不需要用到「=」。但其實

Screen myScreen(5, 5, 'X');

就等於 Screen myScreen=Screen(5, 5, 'X'); 只是比較囉嗦

1:27:59

練習7.28

1:30:00

練習7.29

1:36:39

練習7.30



1:45:00

7.3.3. Class Types

Note Even if two classes have exactly the same member list, they are different types. The members of each class are distinct from the members of any other class (or any other scope).

1:50:00

原來一般的類別引述前面還可以再加上class或struct,這是C語言。剛好今天才訂購了《由片語學習C程式設計(第二版)》。緣起

https://www.facebook.com/oscarsun72/posts/2226635214114267



2:7:44

Class Declarations

2:13:00就像函式一樣,可以宣告一個類別而不一塊兒定義它。

頁279

2:15:20

前向宣告(forward declaration)

class Screen; // declaration of the Screen class

This declaration, sometimes referred to as a forward declaration , introduces the name Screen into the program and indicates that Screen refers to a class type. After a declaration and before a definition is seen, the type Screen is an incomplete type —it’s known that Screen is a class type but not known what members that type contains.

2:25:55

不完整的型別(incomplete type)

對於不完整的類別型別,還能做對它型別物件的參考和指標,以及宣告一個用它作為參數或回傳型別的函式:

We can define pointers or references to such types, and we can declare (but not define) functions that use an incomplete type as a parameter or return type.



2:33:30 資料成員(data member)要定義為一個類別型別,就一定要在它想要成為的那個類別被明確、完整地定義之後才行:

data members can be specified to be of a class type only if the class has been defined.

除了我們會在§7.6描述的一個例外,資料成員只能在一個類別已經定義的前提下被指定為那個類別型別。



因為資料成員(data member)必然是在類別宣告的本體(body)之內,而一個類別在還沒完成整體前是尚未完整定義的類別,就不可能作為其成員的型別來用:

Because a class is not defined until its class body is complete, a class cannot have data members of its own type.

所以一個類別不可能有它自己型別的資料成員(data member)

可是它的資料成員的型別卻可以是指向它的指標或參考







2:49:30

練習7.31

3:23:10

#ifndef XY_H

#define XY_H

class X {

int val = 0;

public:

Y* yPtr;



};

struct Y {

int val = 0;

Y(int v): val(v) {}

X x;

};

#endif // !XY_H

留言

熱門文章