1,先搞清楚private inheritance的行为:
(1)如果class之间是私有继承的关系,编译器不会将一个派生类自动转化为基类.
(2)由基类继承而来的所有成员,在派生类中都会变成private.
2,私有继承:只有实现部分被继承,接口部分应略去.
因此,如果你让D私有继承B,那么你是想采用class B内的某些程序代码,而不是因为B和D的对象有任何概念关系存在.
3,回想一下,laying的意义也是这样.那么如何在laying和private inheritance之间取舍呢?
尽可能使用laying,必要时(当protected members或虚函数牵扯进来)才使用private inheritance.
4,模版的坏处:Stack<int>和Stack<double>编译器默认会把代码完全复制一份,造成代码膨胀.
5,可以借助泛型指针避免代码重用的做法.
泛型指针:class存放的是对象指针
6,laying实现泛型指针:
注:上述代码可能存在的隐患:
有人可能会误用GenericStack.
7,借组private inheritance可以给出更好的实现方案.
实例代码:
(1)如果class之间是私有继承的关系,编译器不会将一个派生类自动转化为基类.
(2)由基类继承而来的所有成员,在派生类中都会变成private.
2,私有继承:只有实现部分被继承,接口部分应略去.
因此,如果你让D私有继承B,那么你是想采用class B内的某些程序代码,而不是因为B和D的对象有任何概念关系存在.
3,回想一下,laying的意义也是这样.那么如何在laying和private inheritance之间取舍呢?
尽可能使用laying,必要时(当protected members或虚函数牵扯进来)才使用private inheritance.
4,模版的坏处:Stack<int>和Stack<double>编译器默认会把代码完全复制一份,造成代码膨胀.
5,可以借助泛型指针避免代码重用的做法.
泛型指针:class存放的是对象指针
6,laying实现泛型指针:
#include <iostream>
using namespace std;
//先定义一个泛型类
class GenericStack
{
public:
GenericStack();
void push(void *t);
void* pop();
void* top();
bool empty();
int size();
~GenericStack();
private:
struct StackNode
{
StackNode(void* t, StackNode *nextNode) : data(t),next(nextNode){}
void* data;
StackNode* next;
};
StackNode* head;
int cnt;
GenericStack(const GenericStack&);
GenericStack& operator=(const GenericStack&);
};
GenericStack::GenericStack() : head(NULL),cnt(0) {}
void GenericStack::push(void* t)
{
head = new StackNode(t, head);
cnt++;
}
void* GenericStack::pop()
{
if (!empty())
{
StackNode* tmp = head;
head = head -> next;
void* tmpData = tmp -> data;
delete tmp;
cnt--;
return tmpData;
}
}
void* GenericStack::top()
{
if (!empty())
return head -> data;
}
bool GenericStack::empty()
{
return head == NULL;
}
int GenericStack::size()
{
return cnt;
}
GenericStack::~GenericStack()
{
while (head)
{
StackNode* tmp = head;
head = head -> next;
delete tmp;
}
}
//laying技术的使用
class IntStack
{
public:
void push(int *t)
{
s.push(t);
}
int* pop()
{
return static_cast<int*>(s.pop());
}
int* top()
{
return static_cast<int*>(s.top());
}
bool empty()
{
return s.empty();
}
int size()
{
return s.size();
}
private:
GenericStack s;
};
class DoubleStack
{
public:
void push(double *t)
{
s.push(t);
}
double* pop()
{
return static_cast<double*>(s.pop());
}
double* top()
{
return static_cast<double*>(s.top());
}
bool empty()
{
return s.empty();
}
double size()
{
return s.size();
}
private:
GenericStack s; //这个成员是核心
};
int main()
{
IntStack myStack;
int a = 20, b = 30, c = 40;
myStack.push(&a);
myStack.push(&b);
myStack.push(&c);
cout << *(myStack.pop()) <<endl;
cout << myStack.size() <<endl;
cout << *(myStack.top()) <<endl;
DoubleStack myStack2;
double da = 20.11, db = 30.22, dc = 40.33;
myStack2.push(&da);
myStack2.push(&db);
myStack2.push(&dc);
cout << *(myStack2.pop()) <<endl;
cout << myStack2.size() <<endl;
cout << *(myStack2.top()) <<endl;
return 0;
}
注:上述代码可能存在的隐患:
有人可能会误用GenericStack.
7,借组private inheritance可以给出更好的实现方案.
实例代码:
#include <iostream>
using namespace std;
//先定义一个泛型类
class GenericStack
{
protected:
GenericStack(); //它的对象无法在外面产生
//因此可以防止有人直接访问GenericStack
void push(void *t);
void* pop();
void* top();
bool empty();
int size();
~GenericStack();
private:
struct StackNode
{
StackNode(void* t, StackNode *nextNode) : data(t),next(nextNode){}
void* data;
StackNode* next;
};
StackNode* head;
int cnt;
GenericStack(const GenericStack&);
GenericStack& operator=(const GenericStack&);
};
GenericStack::GenericStack() : head(NULL),cnt(0) {}
void GenericStack::push(void* t)
{
head = new StackNode(t, head);
cnt++;
}
void* GenericStack::pop()
{
if (!empty())
{
StackNode* tmp = head;
head = head -> next;
void* tmpData = tmp -> data;
delete tmp;
cnt--;
return tmpData;
}
}
void* GenericStack::top()
{
if (!empty())
return head -> data;
}
bool GenericStack::empty()
{
return head == NULL;
}
int GenericStack::size()
{
return cnt;
}
GenericStack::~GenericStack()
{
while (head)
{
StackNode* tmp = head;
head = head -> next;
delete tmp;
}
}
//laying技术的使用
class IntStack : private GenericStack
{
public:
void push(int *t)
{
GenericStack::push(t);
}
int* pop()
{
return static_cast<int*>(GenericStack::pop());
}
int* top()
{
return static_cast<int*>(GenericStack::top());
}
bool empty()
{
return GenericStack::empty();
}
int size()
{
return GenericStack::size();
}
};
class DoubleStack : private GenericStack
{
public:
void push(double *t)
{
GenericStack::push(t);
}
double* pop()
{
return static_cast<double*>(GenericStack::pop());
}
double* top()
{
return static_cast<double*>(GenericStack::top());
}
bool empty()
{
return GenericStack::empty();
}
double size()
{
return GenericStack::size();
}
};
int main()
{
IntStack myStack;
int a = 20, b = 30, c = 40;
myStack.push(&a);
myStack.push(&b);
myStack.push(&c);
cout << *(myStack.pop()) <<endl;
cout << myStack.size() <<endl;
cout << *(myStack.top()) <<endl;
DoubleStack myStack2;
double da = 20.11, db = 30.22, dc = 40.33;
myStack2.push(&da);
myStack2.push(&db);
myStack2.push(&dc);
cout << *(myStack2.pop()) <<endl;
cout << myStack2.size() <<endl;
cout << *(myStack2.top()) <<endl;
return 0;
}