一、理论介绍
C++编程语言的应用范围比较广泛,能够以一种简单灵活的方式帮助开发人员实现许多功能。在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生。 从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。
- 单继承的定义
- class B:public
- {
- < 派生类新定义成员>
- };
- 多继承的定义
- class C:public A,private B
- {
- < 派生类新定义成员>
- };
公有继承(public)、私有继承(private)、保护继承(protected)是常用的三种继承方式。
1. 公有继承(public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
2. 私有继承(private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
3. 保护继承(protected)
保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。
下面列出三种不同的继承方式的基类特性和派生类特性。
public | protected | private | |
公有继承 | public | protected | 不可见 |
私有继承 | private | private | 不可见 |
保护继承 | protected | protected | 不可见 |
在上图中:1)基类成员对派生类都是:共有和保护的成员是可见的,私有的的成员是不可见的。
2)基类成员对派生类的对象来说:要看基类的成员在派生类中变成了什么类型的成员。如:私有继承时,基类的共有成员和私有成员都变成了派生类中的私有成员,因此对于派生类中的对象来说基类的共有成员和私有成员就是不可见的。
为了进一步理解三种不同的继承方式在其成员的可见性方面的区别,下面从三种不同角度进行讨论。
对于公有继承方式
(1) 基类成员对其对象的可见性:
公有成员可见,其他不可见。这里保护成员同于私有成员。
(2) 基类成员对派生类的可见性:
公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员。
(3) 基类成员对派生类对象的可见性:
公有成员可见,其他成员不可见。
所以,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。这里,一定要区分清楚派生类的对象和派生类中的成员函数对基类的访问是不同的。
对于私有继承方式
(1) 基类成员对其对象的可见性:
公有成员可见,其他成员不可见。
(2) 基类成员对派生类的可见性:
公有成员和保护成员是可见的,而私有成员是不可见的。
(3) 基类成员对派生类对象的可见性:
所有成员都是不可见的。
所以,在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承。
对于保护继承方式
这种继承方式与私有继承方式的情况相同。两者的区别仅在于对派生类的成员而言,对基类成员有不同的可见性。
上述所说的可见性也就是可访问性。
关于可访问性还有另的一种说法。这种规则中,称派生类的对象对基类访问为水平访问,称派生类的派生类对基类的访问为垂直访问。
看看这样的例子:
#include<iostream>
using
namespace
std;
//
class
A
//父类
{
private
:
int
privatedateA;
protected
:
int
protecteddateA;
public
:
int
publicdateA;
};
//
class
B :
public
A
//基类A的派生类B(共有继承)
{
public
:
void
funct()
{
int
b;
b=privatedateA;
//error:基类中私有成员在派生类中是不可见的
b=protecteddateA;
//ok:基类的保护成员在派生类中为保护成员
b=publicdateA;
//ok:基类的公共成员在派生类中为公共成员
}
};
//
class
C :
private
A
//基类A的派生类C(私有继承)
{
public
:
void
funct()
{
int
c;
c=privatedateA;
//error:基类中私有成员在派生类中是不可见的
c=protecteddateA;
//ok:基类的保护成员在派生类中为私有成员
c=publicdateA;
//ok:基类的公共成员在派生类中为私有成员
}
};
//
class
D :
protected
A
//基类A的派生类D(保护继承)
{
public
:
void
funct()
{
int
d;
d=privatedateA;
//error:基类中私有成员在派生类中是不可见的
d=protecteddateA;
//ok:基类的保护成员在派生类中为保护成员
d=publicdateA;
//ok:基类的公共成员在派生类中为保护成员
}
};
//
int
main()
{
int
a;
B objB;
a=objB.privatedateA;
//error:基类中私有成员在派生类中是不可见的,对对象不可见
a=objB.protecteddateA;
//error:基类的保护成员在派生类中为保护成员,对对象不可见
a=objB.publicdateA;
//ok:基类的公共成员在派生类中为公共成员,对对象可见
C objC;
a=objC.privatedateA;
//error:基类中私有成员在派生类中是不可见的,对对象不可见
a=objC.protecteddateA;
//error:基类的保护成员在派生类中为私有成员,对对象不可见
a=objC.publicdateA;
//error:基类的公共成员在派生类中为私有成员,对对象不可见
D objD;
a=objD.privatedateA;
//error:基类中私有成员在派生类中是不可见的,对对象不可见
a=objD.protecteddateA;
//error:基类的保护成员在派生类中为保护成员,对对象不可见
a=objD.publicdateA;
//error:基类的公共成员在派生类中为保护成员,对对象不可见
return
0;
}
|
构造函数和析构函数不能被继承
因此构造派生类的对象时,需要对基类数据成员.新增数据成员和成员对象的数据成员进行初始化
派生类构造函数的参数表部分既需要包含子类某些数据成员的初始值,也要包含基类的数据成员的初始值
如果基类没有默认的构造函数,那么派生类必须具有给基类构造函数提供参数的构造函数
派生类构造函数一般语法如下:
- 派生类名::派生类名(参数总表)
- :基类名1(参数表1),...,基类名n(参数表n)
- {
- 初始化语句
- }
当基类有多个构造函数时,编译器根据派生类构造函数为基类构造函数提供的参数初始化列表中的参数类型来确定调用哪个构造函数
派生类的析构函数应当首先对派生类新增普通成员进行清理
然后对派生类新增的对象成员进行清理
最后是对所有从C++类继承来的成员进行清理
二、实例讲解:
#include <iostream.h>
class Base
{
private:
int b_number;
public:
Base( ){} // base第一个无参数的构造函数
Base(int i) : b_number (i) { } // Base有两个构造函数,且构造参数为b_number
int get_number( ) {return b_number;}
void print( ) {cout << b_number << endl;}
};
派生类
class Derived : public Base
{
private:
int d_number;
public:
// constructor, initializer used to initialize the base part of a Derived object.
Derived( int i, int j ) : Base(i), d_number(j) { }; // 派生类D从基类B及其自身的d_number中获得参数,进行构造
// 派生类D对基类B的函数进行重定义或叫隐藏
(重定义(也成隐藏)
(1)不在同一个作用域(分别位于派生类与基类) ;
(2)函数名字相同;
(3)返回值可以不同;
(4)参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载以及覆盖混淆) 。
(5)参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆) 。
重载(overload)
指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断。
(1)相同的范围(在同一个作用域中) ;
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
(5)返回值可以不同;
重写(也称为覆盖 override)
是指派生类重新定义基类的虚函数,特征是:
(1)不在同一个作用域(分别位于派生类与基类) ;
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有 virtual 关键字,不能有 static 。
(5)返回值相同(或是协变),否则报错;<—-协变这个概念我也是第一次才知道…
(6)重写函数的访问修饰符可以不同。尽管 virtual 是 private 的,派生类中重写改写为 public,protected 也是可以的
)void print( )
{
cout << get_number( ) << " ";
// access number through get_number( )
cout << d_number << endl;
}
};
int main( )
{
Base a(2);// 定义一个基类
Derived b(3, 4);// 定义一个派生类
cout << "a is ";
a.print( ); // print( ) in Base
cout << "b is ";
b.print( ); // print( ) in Derived
cout << "base part of b is ";
b.Base::print( ); // print( ) in Base
return 0;
}
没有虚析构函数,继承类没有析构
//Example: non- virtual destructors for dynamically allocated objects.
#include <iostream.h>
#include <string.h>
class Thing
{ public:
virtual void what_Am_I( ) {cout << "I am a Thing./n";}
~Thing(){cout<<"Thing destructor"<<endl;}
};
class Animal : public Thing
{
public:
virtual void what_Am_I( ) {cout << "I am an Animal./n";}
~Animal(){cout<<"Animal destructor"<<endl;}
};
void main( )
{
Thing *t =new Thing;
Animal*x = new Animal;
Thing* array[2];
array[0] = t; // base pointer
array[1] = x;
for (int i=0; i<2; i++) array->what_Am_I( ) ;
delete array[0];
delete array[1];
return ;
}
纯虚函数,多态
#include <iostream.h>
#include <math.h>
class Point
{
private:
double x;
double y;
public:
Point(double i, double j) : x(i), y(j) { }
void print( ) const
{ cout << "(" << x << ", " << y << ")"; }
};
class Figure
{
private:
Point center;
public:
Figure (double i = 0, double j = 0) : center(i, j) { }
Point& location( )
{
return center;
} // return an lvalue
void move(Point p)
{
center = p;
draw( );
}
virtual void draw( ) = 0; // draw the figure
virtual void rotate(double) = 0;
// rotate the figure by an angle
};
class Circle : public Figure
{
private:
double radius;
public:
Circle(double i = 0, double j = 0, double r = 0) : Figure(i, j), radius(r) { }
void draw( )
{
cout << "A circle with center ";
location( ).print( );
cout << " and radius " << radius << endl;
}
void rotate(double)
{
cout << "no effect./n";
} // must be defined
};
class Square : public Figure
{
private:
double side; // length of the side
double angle; // the angle between a side and the x-axis
public:
Square(double i = 0, double j = 0, double d = 0, double a = 0) : Figure(i, j), side(d), angle(a) { }
void draw( )
{
cout << "A square with center ";
location( ).print( );
cout << " side length " << side << "./n"
<< "The angle between one side and the X-axis is " << angle << endl;
}
void rotate(double a)
{
angle += a;
cout << "The angle between one side and the X-axis is " << angle << endl;
}
void vertices( )
{
cout << "The vertices of the square are:/n";
// calculate coordinates of the vertices of the square
}
};
int main( )
{
Circle c(1, 2, 3);
Square s(4, 5, 6);
Figure *f = &c, &g = s;
f -> draw( );
f -> move(Point(2, 2));
g.draw( );
g.rotate(1);
s.vertices( );
// Cannot use g here since vertices( ) is not a member of Figure.
return 0;
}
#include <iostream.h>
#include <string.h>
class Thing
{
public:
virtual void what_Am_I( ) {cout << "I am a Thing./n";}
~Thing(){cout<<"Thing destructor"<<endl;}
};
class Animal : public Thing
{
public:
virtual void what_Am_I( ) {cout << "I am an Animal./n";}
~Animal(){cout<<"Animal destructor"<<endl;}
};
void main( )
{
Thing t ;
Animal x ;
Thing* array[2];
array[0] = &t; // base pointer
array[1] = &x;
for (int i=0; i<2; i++) array->what_Am_I( ) ;
return ;
}
多继承
#include <iostream.h>
class A
{
private:
int a;
public:
A(int i) : a(i) { }
virtual void print( ) {cout << a << endl;}
int get_a( ) {return a;}
};
class B
{
private:
int b;
public:
B(int j) : b(j) { }
void print( ) {cout << b << endl;}
int get_b( ) {return b;}
};
class C : public A, public B
{
int c;
public:
C(int i, int j, int k) : A(i), B(j), c(k) { }// C从A中得到参数i,从B中得到参数j,在c中得到k,实现多参数构造函数
void print( ) {A::print( ); B::print( );}
// use print( ) with scope resolution
void get_ab( ) {cout << get_a( ) << " " << get_b( ) << endl;}
// use get_a( ) and get_b( ) without scope resolution
};
int main( )
{
C x(5, 8, 10);
A* ap = &x;
B* bp = &x;
ap -> print( ); // use C::print( );
bp -> print( ); // use B::print( );
// bp -> A::print( ); // as if x is inherited from B only,
// cannot access A::print( );
x.A::print( ); // use A::print( );
x.get_ab( );
return 0;
}
共同基类的多继承
#include <iostream.h>
class R
{int r;
public:
R(int anInt){ r = anInt;};
printOn(){ cout<<"r="<<r<<endl;} ; };
class A : public R
{
int a;
public:
A(int int1,int int2):R(int2){ a = int1;};};
class B : public R
{
int b;
public:
B(int int1,int int2):R(int2){ b = int1;};};
class C : public A, public B
{
int c;
public:
C(int int1,int int2, int int3):A(int2,int3), B(int2,int3){ c = int1;}
};
int main( )
{
int i;
R rr(10);
A aa(20,30);
B bb (40,50);
C cc(5, 7, 9);
rr.printOn();
aa.printOn(); //inherits R printOn
bb.printOn(); //inherits R printOn
//cc.printOn(); //would give error
return 0;}
虚基类
#include <iostream.h>
class R
{ int r;
public:
R (int x = 0) : r(x) { } // constructor in R
void f( ){ cout<<"r="<<r<<endl;}
void printOn(){cout<<"printOn R="<<r<<endl;}
};
class A : public virtual R
{ int a;
public:
A (int x, int y) : R(x), a(y) { } // constructor in A
void f( ){ cout<<"a="<<a<<endl;R::f();}
};
class B : public virtual R
{int b;
public:
B(int x, int z) : R(x), b(z) { }// constructor in B
void f( ){ cout<<"b="<<b<<endl;R::f();}
};
class C : public A, public B
{ int c;
public:
// constructor in C, which constructs an R object first
C(int x, int y, int z, int w) : R(x), A(x, y), B(x, z), c(w) { }
void f( ){ cout<<"c="<<c<<endl;A::f(); B::f();}
};
void main()
{ R rr(1000);
A aa(2222,444);
B bb(3333,111);
C cc(1212,345,123,45);
cc.printOn(); //uses R printOn but only 1 R..no ambiguity
cc.f(); // shows multiple call of the R::f()
}
#include <iostream.h>
class R
{ int r;
public:
R (int x = 0) : r(x) { } // constructor in R
void f( ){ cout<<"r="<<r<<endl;}
};
class A : virtual public R
{ int a ;
protected:
void fA( ){cout<<"a="<<a<<endl;};
public:
A (int x, int y) : R(x), a(y) { } // constructor in A
void f( ) {fA( ); R::f( );}
};
class B : virtual public R
{ int b;
protected:
void fB( ){cout<<"b="<<b<<endl;};
public:
B (int x, int y) : R(x), b(y) { } // constructor in A
void f( ) {fB( ); R::f( );}
};
class C : public A, public B
{ int c;
protected:
void fC( ){ cout<<"c="<<c<<endl;};
public:
C(int x, int y, int z, int w) : R(x), A(x, y), B(x, z), c(w) { }
void f( )
{
R::f( ); // acts on R stuff only
A::fA( ); //acts on A stuff only
B::fB( ); // acts on B stuff only
fC( ); // acts on C stuff only
}
};
void main()
{ R rr(1000);
A aa(2222,444);
B bb(3333,111);
C cc(1212,345,123,45);
cc.f();
}
私有继承
// Access levels
#include <iostream.h>
class Base
{
private:
int priv;
protected:
int prot;
int get_priv( ) {return priv;}
public:
int publ;
Base( );
Base(int a, int b, int c) : priv(a), prot(b), publ(c) { }
int get_prot( ) {return prot;}
int get_publ( ) {return publ;}
};
class Derived1 : private Base // private inheritance
{
public:
Derived1 (int a, int b, int c) : Base(a, b, c) { }
int get1_priv( ) {return get_priv( );}
// priv not accessible directly
int get1_prot( ) {return prot;}
int get1_publ( ) {return publ;}
};
class Leaf1 : public Derived1
{
public:
Leaf1(int a, int b, int c) : Derived1(a, b, c) { }
void print( )
{
cout << "Leaf1 members: " << get1_priv( ) << " "
// << get_priv( ) // not accessible
<< get1_prot( ) << " "
// << get_prot( ) // not accessible
// << publ // not accessible
<< get1_publ( ) << endl;
} // data members not accessible. get_ functions in Base not accessible
};
class Derived2 : protected Base // protected inheritance
{
public:
Derived2 (int a, int b, int c) : Base(a, b, c) { }
};
class Leaf2 : public Derived2
{
public:
Leaf2(int a, int b, int c) : Derived2(a, b, c) { }
void print( )
{
cout << "Leaf2 members: " << get_priv( ) << " "
// << priv // not accessible
<< prot << " "
<< publ << endl;
} // public and protected data members accessible. get_ functions in Base accessible.
};
class Derived3 : public Base // public inheritance
{
public:
Derived3 (int a, int b, int c) : Base(a, b, c) { }
};
class Leaf3 : public Derived3
{
public:
Leaf3(int a, int b, int c) : Derived3(a, b, c) { }
void print( )
{
cout << "Leaf3 members: " << get_priv( ) << " "
<< prot << " "
<< publ << endl;
} // public and protected data members accessible. get_ functions in Base accessible
};
int main( )
{
Derived1 d1(1, 2, 3);
Derived2 d2(4, 5, 6);
Derived3 d3(7, 8, 9);
// cout << d1.publ; // not accessible
// cout << d1.get_priv( ); // not accessible
// cout << d2.publ; // not accessible
// cout << d2.get_priv( ); // not accessible
cout << d3.publ; // OK
cout << d3.get_prot( ); // OK
Leaf1 lf1(1, 2, 3);
Leaf2 lf2(4, 5, 6);
Leaf3 lf3(7, 8, 9);
// cout << lf1.publ << endl; // not accessible
// cout << lf2.publ << endl; // not accessible
cout << lf3.publ << endl; // OK
return 0;
}
多级继承
// Point-Circle-Cylinder
#include <iostream.h>
// THE POINT CLASS
class Point
{
friend ostream & operator<<(ostream &,Point &);
public:
// constructor
Point (double xval =0, double yval=0 )
{ x=xval; y=yval;};
protected: // accessed by derived class
double x;
double y;
};
ostream & operator << (ostream & os,
Point & apoint)
{
cout <<" Point:X:Y: "<<apoint.x << ","
<< apoint.y<< "/n";
return os;
}
//The Circle class inherits from class Point
class Circle : public Point
{
friend ostream & operator<<(ostream &,Circle&);
public:
Circle (double r=0,double xval=0,double yval=0)
:Point(xval,yval), radius(r)
{
//radius = r;
}
double area()
{
return (3.14159* radius *radius);
}
protected:
double radius;
};
//note casting circle to point
ostream & operator <<(ostream & os, Circle & aCircle)
{
cout<< "Circle:radius:" << aCircle.radius;
os<< aCircle.x << "/n";
os<< aCircle.y << "/n";
return os;
}
// THE CYLINDER CLASS
class Cylinder : public Circle
{
friend ostream & operator << (ostream & ,Cylinder &);
public:
Cylinder (double hv=0,double rv=0,
double xv=0,double yv=0 )
: Circle( xv,yv,rv)
{
height = hv;
}
double area ( );
protected: // may have derived classes
double height;
};
double Cylinder :: area ( )
{ // Note that cylinder area uses Circle area
return 2.0* Circle::area() + 2.0*3.14159* radius*height;
}
ostream & operator << (ostream & os,
Cylinder & acylinder)
{
cout << "cylinder dimensions: ";
cout << "x: " <<acylinder.x;
cout << " y: " <<acylinder.y ;
cout << " radius: " <<acylinder.radius ;
cout << " height: " <<acylinder.height
<< endl;
return os;
}
int main(void)
{
Point p(2,3);
Circle c(7,6,5);
Cylinder cyl(10,11,12,13);
cout << p;
cout << c;
cout << "area of cirle:" << c.area() << endl;
cout<< cyl;
cout<<"area of cylinder:"<< cyl.area()<<endl ;
cout<<"area of cylinder base is "
<< cyl.Circle::area() << endl;
return 0;
}
protected 访问控制属性在继承的意义
//Example of treating derived class object as base class objects. Point------Circle
#include <iostream.h>
// THE POINT CLASS
class Point
{
friend ostream & operator<<(ostream &,Circle&);
public:
Point (double xval =0, double yval=0 ) { x=xval; y=yval;};
public:
void print()
{
cout <<" Point:X:Y: "<<x << "," <<y<< "/n";
}
protected: // accessed by derived class
double x; double y;
};
ostream & operator << (ostream & os, Point & apoint)
{
cout <<" Point:X:Y: "<<apoint.x << ","<< apoint.y<< "/n";
return os;
}
//The Circle class inherits from class Point
class Circle : public Point
{
friend ostream & operator<<(ostream &,Circle&);
public:
Circle (double r=0,double xval=0,double yval=0):Point(xval,yval)
{ radius = r;};
void print()
{
cout<< "Circle:radius:" <<radius<<endl;
cout <<" Point:X:Y: "<<x << "," <<y<< "/n";
}
double area()
{ return (3.14159* radius *radius);};
protected:
double radius;
};
//note casting circle to point
ostream & operator <<(ostream & os, Circle & aCircle)
{
cout<< "Circle:radius:" << aCircle.radius;
cout<< (Point) aCircle << "/n";
return os;
}
//We will look at a few main programs based on previous class definitions. Casting and assignments
void main (void )
{
Point p(2,3); cout <<"Point P= "<< p;
Point pp(0,0); cout <<"Point PP= "<< pp;
Circle c(7,6,5); cout <<"Circle c= "<< c; //radius =7
pp = p; cout <<"Point PP= "<< pp; //built in assign =
// a circle is a member of the point class so assign a circle to a point.
pp = c; //legal; also assignment O.K.
cout <<"Point PP= "<< pp;
pp= (Point) c; // but better use the cast
cout <<"Point PP= "<< pp; //note we get only the point part of the Circle
//c = (Circle) pp; // illegal Cannot convert 'class Point' to 'class Circle'
//c=pp; //illegal assignment not defined
Point* p;
p = &c;
P->print(); //call base class print
((Circle*)p)->print();
Point& r = c;
r.print();
((Circle&)r).print();
}
类的兼容性规则
#include <iostream.h>
class Base
{
public:
void func( )
{cout << "Base class function./n";}
};
class Derived : public Base
{
public:
void func( )
{cout << "Derived class function./n";}
};
void foo(Base b)
{ b.func( ); }
int main( )
{
Derived d;
Base b;
Base * p = &d;
Base& br = d;
b = d;
b.func( );
d.func( );
p -> func( );
foo(d);
br.func( );
return 0;
}
虚析构函数,防止内存泄露
#include <iostream.h>
#include <string.h>
class Base
{
protected:
int id;
char * name;
public:
// default constructor
Base(int a = 0, char * s = "") : id(a)
{
if (!s)
{
name = NULL;
}
else
{
name = new char[strlen(s) + 1];
strcpy(name, s);
}
cout << "base default constructor/n";
}
// copy constructor
Base(const Base& b) : id(b.id)
{
if (!b.name) { name = NULL; }
else
{
name = new char[strlen(b.name) + 1];
strcpy(name, b.name);
}
cout << "base copy constructor/n";
}
// destructor
~Base( )
{
if( name != NULL ) delete [ ] name;
cout << "base destructor/n";
}
const Base& operator= (const Base& b);
friend ostream& operator << (ostream&, const Base&);
};
const Base& Base:perator= (const Base& b)
{
if (this != &b) // Check if an object is assigned to itself.
{
id = b.id;
delete [ ] name; // Destroy the old object.
if (!b.name) { name = NULL; }
else
{
name = new char[strlen(b.name) + 1];
strcpy(name, b.name);
}
}
cout << "base assignment operator/n";
return *this;
}
ostream& operator << (ostream& out, const Base& b)
{
out << "Base member id = " << b.id << endl;
out << "Base member name = " << b.name << endl;
return out;
}
class Derived : public Base
{
private:
float f;
char * label;
public:
// default constructor
Derived(int a = 0, char * s = "", float x = 0, char * t = "") : Base(a, s), f(x)
{
if (!t) { label = NULL; }
else
{
label = new char [strlen(t) + 1];
strcpy(label, t);
}
cout << "derived default constructor/n";
}
// copy constructor
Derived(const Derived& d) : Base(d), f(d.f)
// d used as an instance of Base
{
if(!d.label) { label = NULL; }
else
{
label = new char [strlen(d.label) + 1];
strcpy(label, d.label);
}
cout << "derived copy constructor/n";
}
// destructor
~Derived( )
{
delete [ ] label;
cout << "derived destructor/n";
}
const Derived& operator= (const Derived& d);
friend ostream& operator << (ostream&, const Derived&);
};
const Derived& Derived:perator= (const Derived& d)
{
if (this != &d)
{
delete [ ] label;
Base:perator=(d); // Assign the Base part of d to the Base
// part of the object that calls this operator;
f = d.f;
if (!d.label) { label = NULL; }
else
{
label = new char [strlen(d.label) + 1];
strcpy(label, d.label);
}
cout << "derived assignment operator/n";
}
return *this;
}
ostream& operator << (ostream& out, const Derived& d)
{
out << (Base)d; // Convert d to Base object to output Base members.
out << "Derived member f = " << d.f << endl;
out << "Derived member label = " << d.label << endl;
return out;
}
int main( )
{
Derived d1;
Derived d2(d1);
return 0;
}