C++: Using struct like a class / Nested struct / Global scope resolution inside struct
整理自 Thinking in C++。
Using struct
like a class
整个第四章的中心应该是安利 class,所以一上来说了 C lib 这里不好那里不好。然后改进的切入点就是 “why not make functions members of structs?”,于是就有了这样 struct
的新用法(部分代码省略):
//: C04:CppLib.h
// C-like library converted to C++
struct Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
// Functions!
void initialize(int size);
void cleanup();
// 注意:你在 header 里直接写函数的实现也是可以的:
/*
void initialize(int size) {
...
}
*/
};
//: C04:CppLib.cpp
// C library converted to C++
// Declare structure and functions:
#include "CppLib.h"
#include <iostream>
using namespace std;
void Stash::initialize(int size) {
this->size = size; // 这里 this 是 pointer,不像 java 是 ref
quantity = 0;
storage = 0;
next = 0;
}
void Stash::cleanup() {
if(storage != 0) {
cout << "freeing storage" << endl;
delete []storage;
}
}
上述 C++ style struct
和 old school 的 C style struct
的区别在于:
- 不需要
typedef
式,声明变量时也不需要写全称struct Stash s;
,直接写Stash s;
就好了(当然 C++ 下写全称也不会判错) - 可以直接在
struct
内部写函数的实现(直接 declare + define)- 有了 member function 之后,可以直接
s.cleanup();
了,不像原来只能cleanup(&s);
- 有了 member function 之后,可以直接
- 如果要分离函数声明和实现,那么在 cpp 文件里的写法要用
::
,变成void Stash::initialize(int size) { ... }
::
: scope resolution operator- 注意在 cpp 文件里,你看不到 field 名,但是可以像 Java 一样直接用。我们也不是每时每刻都在写
this.foo = xxx;
。 - 这样分一个 header 一个 cpp,也是一种 “接口与实现的分离”
~~~~~~~~~~ 2015-05-15 更新 ~~~~~~~~~~
struct
的 member 默认是public
class
member 默认是private
struct
也可以继承,而且默认是public
继承class
继承默认是private
继承
~~~~~~~~~~ 2015-05-15 更新完毕 ~~~~~~~~~~
Nested struct
#ifndef STACK_H
#define STACK_H
struct Stack {
struct Link {
void* data;
Link* next;
void initialize(void* dat, Link* nxt);
}* head;
void initialize();
void push(void* dat);
void* peek();
void* pop();
void cleanup();
};
#endif // STACK_H
注意实现的写法:
// using an additional level of scope resolution
void Stack::Link::initialize(void* dat, Link* nxt) {
data = dat;
next = nxt;
}
void Stack::initialize() { head = 0; }
void Stack::push(void* dat) {
Link* newLink = new Link; // 直接使用 Nested struct,不需要什么特殊的写法
newLink->initialize(dat, head);
head = newLink;
}
// ...
Global scope resolution inside struct
主要的目的是想在 struct
内部访问到 global 的同名 function 或者 variable,注意写法:
int a;
void f() {} // do nothing
struct S {
int a;
void f();
};
void S::f() {
::f(); // call the global f()
::a++; // increase the global a
f(); // call this->f(), i.e. the function itself
a++; // increase this->a;
}
Comments