C++编程思想 第1卷 第14章 继承和组合 非自动继承的函数

本文探讨了C++中函数的合成与继承机制,重点分析了构造函数、析构函数及赋值运算符在继承过程中的行为。通过具体示例,展示了如何在派生类中正确调用基类的构造函数和赋值运算符,以及如何实现类型转换。

不是所有的函数都能自动地从基类继承到派生类中的

operator= 也不能被继承,因为它完成类似于构造函数的活动

在继承工程中,如果不亲自创建这些函数,编译器就会生成它们

//: C14:SynthesizedFunctions.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Functions that are synthesized by the compiler
#include <iostream>
using namespace std;

class GameBoard {
public:
  GameBoard() { cout << "GameBoard()\n"; }
  GameBoard(const GameBoard&) { 
    cout << "GameBoard(const GameBoard&)\n"; 
  }
  GameBoard& operator=(const GameBoard&) {
    cout << "GameBoard::operator=()\n";
    return *this;
  }
  ~GameBoard() { cout << "~GameBoard()\n"; }
};

class Game {
  GameBoard gb; // Composition
public:
  // Default GameBoard constructor called:
  Game() { cout << "Game()\n"; }
  // You must explicitly call the GameBoard
  // copy-constructor or the default constructor
  // is automatically called instead:
  Game(const Game& g) : gb(g.gb) { 
    cout << "Game(const Game&)\n"; 
  }
  Game(int) { cout << "Game(int)\n"; }
  Game& operator=(const Game& g) {
    // You must explicitly call the GameBoard
    // assignment operator or no assignment at 
    // all happens for gb!
    gb = g.gb;
    cout << "Game::operator=()\n";
    return *this;
  }
  class Other {}; // Nested class
  // Automatic type conversion:
  operator Other() const {
    cout << "Game::operator Other()\n";
    return Other();
  }
  ~Game() { cout << "~Game()\n"; }
};

class Chess : public Game {};

void f(Game::Other) {}

class Checkers : public Game {
public:
  // Default base-class constructor called:
  Checkers() { cout << "Checkers()\n"; }
  // You must explicitly call the base-class
  // copy constructor or the default constructor
  // will be automatically called instead:
  Checkers(const Checkers& c) : Game(c) {
    cout << "Checkers(const Checkers& c)\n";
  }
  Checkers& operator=(const Checkers& c) {
    // You must explicitly call the base-class
    // version of operator=() or no base-class
    // assignment will happen:
    Game::operator=(c);
    cout << "Checkers::operator=()\n";
    return *this;
  }
};

int main() {
  Chess d1;  // Default constructor
  Chess d2(d1); // Copy-constructor
//! Chess d3(1); // Error: no int constructor
  d1 = d2; // Operator= synthesized
  f(d1); // Type-conversion IS inherited
  Game::Other go;
//!  d1 = go; // Operator= not synthesized 
           // for differing types
  Checkers c1, c2(c1);
  c1 = c2;
  getchar();
} ///:~

GameBoard和Game的构造函数和operator= 都自己作了声明,所以我们能知道
编译器何时使用它们

在main()中,调用了为派生类Class生成的默认构造函数和拷贝构造函数

在Chess中,使用成员函数赋值,operator=也被作为一个新的函数生成,因为
该函数在新类中没有被显式地写出

生成的operator=仅仅作用于同种类型对象

Game的拷贝构造函数和赋值运算符显式地调用了成员对象的拷贝构造函数和
赋值运算符

Checkers显式地写了默认构造函数,拷贝构造函数和赋值运算符

输出
GameBoard()
Game()
GameBoard(const GameBoard&)
Game(const Game&)
GameBoard::operator=()
Game::operator=()
Game::operator Other()
GameBoard()
Game()
Checkers()
GameBoard(const GameBoard&)
Game(const Game&)
Checkers(const Checkers& c)
GameBoard::operator=()
Game::operator=()
Checkers::operator=()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值