- /* coordinate.h */
-
#ifndef __COORDINATE_H
-
#define __COORDINATE_H
-
-
class TCoordinate {
-
private:
-
int tc_x, tc_y;
-
public:
-
TCoordinate ():tc_x(0), tc_y(0) { }
-
TCoordinate(int x, int y):tc_x(x), tc_y(y) { }
-
void Setxy(int x, int y);
-
int Getx() const;
-
int Gety() const;
-
};
-
-
#endif
/* coordinate.cpp */
#include "coordinate.h"
void TCoordinate::Setxy(int x,int y)
{
tc_x = x;
tc_y = y;
}
int TCoordinate::Getx()const
{
return tc_x;
}
int TCoordinate::Gety()const
{
return tc_y;
}
/* color.h */
#ifndef __COLOR_H
#define __COLOR_H
#include "coordinate.h"
typedef enum
{
UNKNOWN, RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}TColors;
class TColor:public TCoordinate {
private:
TColors tc_color;
static const char* colornames[]; //指针数组在cpp文件初始化,可以与enum TColors存放一致
public:
TColor():TCoordinate(),tc_color(UNKNOWN) { } //用逗号,在继承基础上增加一项初始化,方法1
TColor(TColors color, int x, int y);
void SetColor(TColors color) { tc_color = color; }
TColors GetColor () const { return tc_color; }
const char * StrColor()const;
};
#endif
/*color.cpp */
#include "color.h"
const char *TColor::colornames[] = { "Unknown", "Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet" };TColor::TColor(TColors color, int x, int y):
TCoordinate(x,y) //继承初始化,方法2
{
tc_color = color;
}
const char *TColor::StrColor() const
{
if (tc_color < RED || tc_color > VIOLET)
return colornames[UNKNOWN];
else
return colornames[tc_color];
}
/* tcoord.cpp */
#include
#include "coordinate.h"
using namespace std;
void display(const char *msg, TCoordinate &tc);
int main()
{
TCoordinate t1;
display("Default object",t1);
TCoordinate t2(45, 218);
display("parameterized object",t2);
t1.Setxy(100, 200);
display("After calling setxy()",t1);
return 0;
}
void display(const char * msg,TCoordinate & tc)
{
cout << msg << endl;
cout << "x == " << tc.Getx() << ";y == " << tc.Gety();
cout << endl;
}
/* tcolor.cpp */
#include
#include "coordinate.h"
#include "color.h"
using namespace std;
void display(const char *msg, TColor &tc);
int main()
{
TColor color_object(ORANGE, 45, 67);
display("Original object", color_object);
color_object.SetColor(GREEN);
color_object.Setxy(125, 250);
display("After function calls", color_object);
return 0;
}
void display(const char *msg, TColor &tc)
{
cout << msg << endl;
cout << "x == " << tc.Getx() << ";y == " << tc.Gety();
cout << ";color= " << tc.StrColor();
cout << "(" << tc.GetColor() << ")";
cout << endl;
}
编译:
g++ -c coordinate.cpp
g++ -c color.cpp
g++ -ggdb3 -o tcoord tcoord.cpp coordinate.o
g++ -ggdb3 -o tcolor tcolor.cpp color.o coordinate.o
/* label.h */
#ifndef __TLABEL_H
#define __TLABEL_H
#include "color.h" //Need TColor
class TLabel:public TColor {
private:
char *t1_label;
public:
TLabel():TColor(){ t1_label = NULL; } //不要参数的默认值初始化
TLabel(const char *label, TColors color, int x, int y);
TLabel(const TLabel ©);
~TLabel(){ delete t1_label; }
const char *Getlabel()const { return t1_label; }
void SetLabel(const char *label);
void operator=(const TLabel ©);
};
#endif
/* label.cpp */
#include
#include "label.h"
TLabel::TLabel(const char * label,TColors color,int x,int y):
TColor(color, x, y)
{
t1_label = NULL; //so SetLabel can create string
SetLabel(label);
}
TLabel:: TLabel(const TLabel ©):
TColor(copy)
{
t1_label = NULL;
SetLabel(copy.t1_label);
}
void TLabel::SetLabel(const char * label)
{
delete[]t1_label; //先删除旧值
t1_label = NULL; //指针置空
if ( label != NULL )
{
t1_label = new char[strlen(label) + 1];
strcpy(t1_label, label);
}
}
void TLabel::operator=(const TLabel ©)
{
if (this == ©) return; //比较地址
Setxy(copy.Getx(), copy.Gety());
SetColor(copy.GetColor());
SetLabel(copy.t1_label);
}
/* tlabel.cpp */
#include
#include "label.h"
using namespace std;
void display(const char *msg, TLabel &t1);
int main()
{
TLabel test("Test Label", RED, 100, 200);
display("Test object", test);
TLabel copy_object(test);
display("Copy constructed object", copy_object);
TLabel dest_object;
display("Object before copy", dest_object);
dest_object = test;
display("Object after copy", dest_object);
return 0;
}
void display(const char *msg, TLabel &t1)
{
cout << msg << endl;
cout << "x == " << t1.Getx() << ";y == " << t1.Gety();
cout << ";color = " << t1.StrColor();
cout << "(" << t1.GetColor() << ")";
cout << ";" << t1.Getlabel();
cout << endl;
}
g++ -ggdb3 -o tlabel tlabel.cpp label.o color.o coordinate.o
./tlabel 的输出有点怪异,最后一条"Object after copy"结果在cout中输不出来,未明白其中原因,或者是编译器问题。
Tlabel类多层继承,下面的类TTest则演示了对象复制时,定义对象复制构造函数与操作符(=)重载的重要性。在包含有动态内存分配的变量时(char *t1_label),这两个函数的重定义是必须的,否则可能产生不可预测的后果
/* copy.cpp */
#include
#include "label.h"
using namespace std;
class TTest:public TLabel {
private:
int count;
public:
TTest():TLabel(), count(123) { }
TTest(const TTest ©);
void operator=(const TTest ©);
int GetCount()const { return count; }
};
void display(const char *msg, TTest &tx);
int main()
{
TTest tx, ty;
display("New object (tx)", tx);
display("New object (ty)", ty);
ty.SetLabel("test string");
ty.SetColor(VIOLET);
ty.Setxy(456, 789);
display("Modified (ty)", ty);
tx = ty;
display("After (tx = ty)", tx);
TTest tz(ty);
display("Copy constructed tz", tz);
return 0;
}
TTest::TTest(const TTest ©):TLabel(copy)
{
count = copy.count;
}
void TTest::operator=(const TTest ©)
{
if (this == ©) return;
*(TLabel *)this = copy; //使用父类operator=()函数(或c++自动产生的)处理对象复制。但 *this=copy 是行不通的;这会使TTest对象复制到this指示的对象,导致递归的函数调用TTest::operator=(),使堆栈很快占满。要告诉C++,this指向TLabel类型的祖先对象,可以用类型校正做这个工作。 类型校正表达式(TLabel*)指出this实际寻址TLabel对象;这是可接受的因为TTest是改进的TLabel对象。外面的星号告诉编译器间接引用类型校正指针。结果是调用TTest::operator=(),以安全处理所有数据成员的复制
count = copy.GetCount();
}
void display(const char *msg, TTest &tx)
{
cout << msg << endl;
cout << "x == " << tx.Getx() << ":y = z" << tx.Gety();
cout << ";color = " << tx.StrColor();
cout << "(" << tx.GetColor() << ')';
cout << "; count = " << tx.GetCount();
cout << endl;
}
[root@test gnu_cpp]# ./copy
New object (tx)
x == 0:y = z0;color = Unknown(0); count = 123
New object (ty)
x == 0:y = z0;color = Unknown(0); count = 123
Modified (ty)
x == 456:y = z789;color = Violet(7); count = 123
After (tx = ty)
x == 456:y = z789;color = Violet(7); count = 123
Copy constructed tz
x == 456:y = z789;color = Violet(7); count = 123