Chinaunix首页 | 论坛 | 博客
  • 博客访问: 857916
  • 博文数量: 254
  • 博客积分: 5350
  • 博客等级: 大校
  • 技术积分: 2045
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-27 13:27
文章分类

全部博文(254)

文章存档

2015年(1)

2014年(9)

2013年(17)

2012年(30)

2011年(150)

2010年(17)

2009年(28)

2008年(2)

分类: C/C++

2011-11-19 09:29:59

  1. /* coordinate.h */
  2. #ifndef __COORDINATE_H
  3. #define __COORDINATE_H

  4. class TCoordinate {
  5. private:
  6.     int tc_x, tc_y;
  7. public:
  8.     TCoordinate ():tc_x(0), tc_y(0) { }
  9.     TCoordinate(int x, int y):tc_x(x), tc_y(y) { }
  10.     void Setxy(int x, int y);
  11.     int Getx() const;
  12.     int Gety() const;
  13. };

  14. #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

阅读(755) | 评论(0) | 转发(0) |
0

上一篇:g++ 编译器选项

下一篇:类的多态

给主人留下些什么吧!~~