AOP-Chap14-Transition to C++

Chap14 Transition to C++

1 Objected-Oriented Programming

struct myStruct {
	int a;
	int b;
};
int main(void) {
	myStruct x;
	return 0;
}
class myClass {
	int a;
	int b;
};
int main(void){
	myClass x;
	return 0;
}

AOP-Chap14-Transition to C++

1.1 Access Control

  • 3 levels of access(visibility) --> public, private, protected
  • public --> can be accessed by any piece of code
  • private --> can only be accessed by code within that class
  • default access
    • struct --> public
    • class --> private
class BankAccount {
private:
	double balance;
public:
	void deposit(double amount) { 
		balance += amount;
	}
	double withdraw(double desiredAmount) {
		if (desiredAmount <= balance) { 
			balance -= desiredAmount; 
			return desiredAmount;
		}
		else {
			double actualAmount = balance;
			balance = 0;
			return actualAmount; 
		}
	}
	double getBalance() {
		return balance; 
	}
	void initAccount() {
		balance = 0;
	}
}; 	

AOP-Chap14-Transition to C++

1.2 encapsulate封装

  • Classes encapsulate—combine into a single logical unit— the data and methods that act on them
BankAccount myAccount; //declare a variable of type BankAccount
myAccount.initAccount(); //call initAccount() on myAccount
myAccount.deposit(42.50); //call deposit(42.50) on myAccount
  • T * const this
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++

1.3 const Methods

  • 其中的“const”限定了getX()函数中不能有任何改变其所属对象成员变量值的功能,如果有则会在编译阶段就报错
  • 在花括号前加const
//const T * const this
class Point {
private:
	int x;
	int y; 
public:
	void setX(int new_x) { 
		x = new_x;
	}
	void setY(int new_y) {
		y = new_y; 
	}
	int getX() const { 
		return x;
	}
	int getY() const {
		return y; 
	}
};
  • can invoke a const method upon a const object but cannot invoke a non-const method upon a const object
void someMethod(const Point * p) {
	int x = p->getX(); //legal: getX() is const
	p->setX(42);  //illegal: setX is not const
				  //but *p is const!
}

1.4 Plain Old Data

  • plain old data (POD) classes -> all POD types have direct C analogs—they are just sequences of fields in memory that you could copy around freely
  • Exception: if you declare functions (a.k.a. methods) inside of a class or struct, they do not make the type non-POD (unless they are virtual functions)
  • the code for functions is just placed with the rest of the code in memory and just takes the extra this parameter to tell which object it is currently operating on 代码实际不在object里
  • 以下两个代码块相同
class MyClass {
public:
	int x;
	int y;
	int getSum() const { return x + y; }
};
typedef struct {
	int x;
	int y;
} MyClass;

int getSum (const MyClass * const this) {
	return this->x + this->y;
}
  • can allocate POD types with malloc, copy with memcpy, and deallocate them with free.
  • With any non- POD type, you cannot work on the “raw” memory directly in a safe way, whether it is allocating, copying, or deallocating that memory. Instead, you have to use the C++ operators that know how to work with non- POD types properly.

1.5 Static Members

  • static means that there is one “box” shared by all instances of the BankAccount class, not one box per instance
  • 实际上在class内没有box,在外面有box,且要在class外单独定义
class BankAccount {
private:
	static unsigned long nextAccountNumber; 
	unsigned long accoutNumber;
	double balance;
public:
	unsigned long getAccountNumber() const { 
		return accoutNumber;
	}
	void deposit(double amount) {
 		 balance += amount;
	}
	double withdraw(double desiredAmount) { 
		if (desiredAmount <= balance) {
    		balance -= desiredAmount;
			return desiredAmount; 
		}
		else {
			double actualAmount = balance; 
			balance = 0;
			return actualAmount;
		} 
	}
	double getBalance() const { 
		return balance;
	}
	void initAccount() {
		accoutNumber = nextAccountNumber; 
		nextAccountNumber++;
		balance = 0; //we will see a better way to do this later
	}
};

unsigned long BankAccount::nextAccountNumber = 0;//:: scope resolution operator 作用域解析    在main运行前运行
  • Static methods in a class cannot access non-static members of the class because unlike non-static methods, they do not have a this pointer passed to them—they operate on no particular object.

1.6 Classes Can Contain Other Types

  • 内部类
class BankAccount {
public:
	typedef double money_t;
private:
	class Transaction { 
	public:
  		money_t amount;
		timeval when;
	};
	money_t balance;
	Transaction * transactions;
//other stuff elided...
};
  • 在类外面用money_t要用BankAccount::money_t; 在里面用money_t
  • 私有内部类永远跑不出外部类,外部类的外部世界不会有私有内部类的实例化且不会有该类型出现
  • 外部类可以访问内部类,根据内部类的可见性
  • methods of an inner class do not have direct access to non- static members of the outer class. methods inside the inner class have a this pointer that points at the object that is an instance of that inner class (e.g., it is a pointer to a Transaction), and does not have a pointer to the outer-class instance (e.g., BankAccount) that created them (in fact, there might not be one). If we want to let the inner class reference the outer class, we can do so easily by having a field in the inner class that is a pointer to the outer class type and initializing it to point at the appropriate outer-class instance.

1.7 The Basics of Good OO Design

  • Classes are nouns. Methods are verbs.
  • Keep classes small and to their purpose.
  • Be as general as you can be, but no more.
  • Avoid “Manager” classes.

2 References

  • reference不能是NULL,一开始就要初始化,自动解引用,不能被更改
  • 错误: int && x int&* x
  • 正确:int *&x a reference to a pointer
  • 指针可以进行数学运算,但reference不能
int f(int & x, int y) {
	int z = x + y; 
	x = z;
	return z - 2;
}
int g(int x) {
	int z = f (x, 3); 
	int & r = z;
	r++;
	return z * x;
}
int f(int * const x, int y) {
	int z = (*x) + y; 
	(*x) = z;
	return z - 2;
}
int g(int x) {
	int z = f (&x, 3); 
	int * const r = &z;
	(*r)++;
	return z * x;
}
  • 以上两者等价,可以互相转换(大多数情况 -> 当一个const reference初始化时被赋的不是lvalue时不成立 -> const int & x = 3 此外,pointer和reference数据类型不同)
    • Declaration: T & --> T * const
    • Initialization: 右边z --> &z ; 调用function的形参–> 加*
    • Uses: 解引用–> 前面加*
  • a call to a function that returns a (non-const) reference may be used as the left side of an assignment statement
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++

3 Namespaces 命名空间

namespace dataAnalysis {
	class DataPoint { ... };
	class DataSet { ... };
	DataSet combineDataSets(DataSet * array, int n);
}
  • 两种方法 reference a name declared inside of a namespace
    1. :: --> fully qualified name --> std::vector
    2. using namespace std; 然后正常使用vector类即可 --> open the entire namespace, and could just write vector to refer to std::vector
      using std::vector; --> bring only the name vector from the std namespace into scope --> preferred
  • using可同时打开多个namespace,但出现同名需要指出想要的函数

4 Function Overloading 函数重载

int f(int x, double d) {...}
double f(double d, int x) {...}
void f(int y) {...}
int f(double d) {...}
double f(void) {}
int f(int * p) {}
int f(const int * p) {} 
  • only overload functions when they perform the same task but on different types
  • only overload functions in such a way that understanding what the “best choice” is for a particular call is straightforward

4.1 Name Mangling 名称修改

  • name mangling—adjusting the function names to encode the parameter type information, as well as what class and namespace the function resides inside of—so that each name is unique
  • mix C and C++ code, the C++ compiler must be explicitly informed of functions that were compiled with a C compiler by declaring them extern “C”
extern "C" {
	void someFunction(int x);
	int anotherFunction(const char * str);
}

5 Operator Overloading

class Point {
private:
	int x;
	int y;
public:
	Point operator+(const Point & rhs) const { 
		Point ans;
		ans.x = x + rhs.x;
		ans.y = y + rhs.y;
		return ans; 
	}
};	
  • the first (left) operand is the this object
  • pass a const reference rather than the value so that avoid copying the entire object as we pass the parameter (which is generally the correct way to pass the right-operand argument of an overloaded operator)
Matrix operator+(const Matrix & rhs) {//2个矩阵相加
	//implementation goes here
}	
  • add another Matrix to the current one, updating the current matrix with the sum
Matrix & operator+=(const Matrix & rhs) {
	//implementation goes here
	return *this;
}	
  • in the case of operators that modify the object they are inside of, such as +=, they return a reference to that object
  • their return type is a reference to the their own class type, and they return *this
  • when returning *this, a reference (the return value) is being initialized, thus the address is implicitly taken; that is, the pointer is &*this, which is just this
MatrixRow & operator[](int index) {
	//code here
}
const MatrixRow & operator[](int index) const {
	//implementation here
}
  • get a const (i.e., read-only) row from a const Matrix
    AOP-Chap14-Transition to C++
    AOP-Chap14-Transition to C++

6 Other Aspects of Switching to C++

6.1 Compilation

G++ -stg=gnu++98

6.2 bool type

bool a = true;
bool b = false;
  • C++ will still respect C-style use of an integer as meaning false if the integer is 0 and true otherwise; however, you should generally use bool for the type of parameters and variables that represent a boolean value

6.3 void Pointers

  • In C, we can assign any pointer type to a void pointer and assign a void pointer to any pointer type without a cast
  • C++ removes this flexibility and requires an explicit cast

6.4 Standard Headers

#include <vector>
  • cstdlib for stdlib.h and cstdio for stdio.h
  • they are placed in the std namespace (so cstdio would provide std::printf) 它们不在global scope里,属于别的namespace

6.5 Code Organization

//header file
class BankAccount {
private:
	double balance;
public:
	void deposit(double amount) ;
	double withdraw (double desiredAmount); 
	double getBalance() const;
	void initAccount();
};

//.cpp file
#include "bank.h"

void BankAccount::deposit(double amount) {
	balance += amount;
}

double BankAccount::withdraw(double desiredAmount) {
	if (desiredAmount <= balance) { 
		balance -= desiredAmount; 
		return desiredAmount;
	}
	else {
		double actualAmount = balance; 
		balance = 0;
		return actualAmount;
	}
}

double BankAccount::getBalance() const {
	return balance;
}

void BankAccount::initAccount() {
	balance = 0; we will see a better way to do this later
}

6.6 Default Values

  • arguments that are omitted must be the rightmost arguments of the call
int f(int x, int y = 3, int z = 4, bool b = false);

f(9);  //x=9,y=3,z=4,b=false
f(9, 8);  //x=9,y=8,z=4,b=false
f(9, 8, 7);  //x=9,y=8,z=7,b=false
f(9,8,7,true); //x=9,y=8,z=7,b=true
  • use default parameters, you should specify them in the prototype in the header file, and only in the prototype in the header file

6.7 Reference Material

http://www.cplusplus.com/

上一篇:获取Dom节点实现显示以及隐藏侧边栏(transform: translate(100%,0); transition: all 2s;)


下一篇:css3属性