模板类继承问题

在看c++沉思录时候,抄了段代码到机器上运行发现死活过不了编译.

代码如下:

/*
 * C++Rumination.cpp
 *
 *  Created on: Jun 2, 2013
 *      Author: root
 */
#include <iostream>
#include <cstdio>
using namespace std;

template <class T> class Array;
template <class T> class Array_data;
template <class T> class Pointer;
template <class T> class ptr_to_const;

template<class T>
class Array_data {//We can solve any problem by introducing an extra level of indirection
	friend class Array<T>;
	friend class ptr_to_const<T>;
	friend class Pointer<T>;
	Array_data(unsigned size = 0) :
		data(new T[size]), sz(size), use(1) {
	}
	~Array_data() {
		delete data;
	}

	const T& operator[](unsigned idx) const {
		if (idx >= sz) {
			throw "Array subscript out of range";
		}
		return data[idx];
	}

	T& operator[](unsigned idx) {
		if (idx >= sz) {
			throw "Array subscript out of range";
		}
		return data[idx];
	}

	Array_data(const Array_data &);
	Array_data & operator=(const Array_data &);
	T * data;
	unsigned sz;
	int use; // use count technique
};

template<class T>
class Array {	
public:
	friend class ptr_to_const<T>;
	friend class Pointer<T>;
	Array(unsigned size) :
		data(new Array_data<T> (size)) {
	}
	~Array() {
		if (--data->use == 0) {
			delete data;
		}
	}

	const T& operator[](unsigned idx) const {
		return (*data)[idx];
	}
	T& operator[](unsigned idx) {
		return (*data)[idx];
	}
private:
	Array(const Array &);
	Array & operator=(const Array &);
	Array_data<T> *data;
};

template<class T> class ptr_to_const{
public:
	ptr_to_const(const Array<T> & a, unsigned n = 0) :
		ap(a.data), sub(n) {
		++ap->use;
	}
	ptr_to_const() :
		ap(0), sub(0) {
	}
	ptr_to_const(const ptr_to_const<T> &p) :
		ap(p.ap), sub(p.sub) {
		if (ap)
			++ap->use;
	}
	~ptr_to_const() {
		if (ap && --ap->use)
			delete ap;
	}
	ptr_to_const & operator=(const ptr_to_const<T> & p) {
		if (this != p) {
			if (p.ap)
				p.ap->use++;
			if (ap && --ap->use == 0) {
				delete ap;
			}
			ap = p.ap;
			sub = p.sub;
		}
		return *this;
	}

	const T & operator*()const {
			if (!ap)
				throw "* of an unbound Pointer";
			return (*ap)[sub];
	}
protected:
	Array_data<T> * ap;
	unsigned sub;
};

template<class T>
class Pointer: public  ptr_to_const<T>{
public:
	Pointer(Array<T> & a, unsigned n = 0):
		ptr_to_const<T>(a, n){
	}
	Pointer(){}
	T & operator*()const {
		if (!ap)//出错地方
			throw "* of an unbound Pointer";
		return (*ap)[sub];//出错地方
	}
};
int main(){
	Array<int> * ap = new Array<int> (10);
	(*ap)[0] = 1;
	Pointer<int> p(*ap, 0);
	delete ap;
	cout << *p << endl;
	int t;
	cin>>t;
}
错误:
--------------------配置: mingw5 - CUI Debug, 编译器类型: MinGW--------------------

检查文件依赖性...
正在编译 C:\Users\Administrator\AppData\Roaming\C-Free\5.0\samples\未命名2.cpp...
[Error] C:\Users\Administrator\AppData\Roaming\C-Free\5.0\samples\未命名2.cpp:124: error: `ap' was not declared in this scope
[Error] C:\Users\Administrator\AppData\Roaming\C-Free\5.0\samples\未命名2.cpp:126: error: `ap' was not declared in this scope
[Error] C:\Users\Administrator\AppData\Roaming\C-Free\5.0\samples\未命名2.cpp:126: error: `sub' was not declared in this scope

各编译器做法不一样,我用的g++是过不了的,vc下的话是可以通过的.
google了下发现有很多人碰到了相同的问题.
最后在effective c++ item43 找到了答案.
解释如下:
当编译器遭遇template<class T>
class Pointer: public  ptr_to_const<T>
它并不知道ptr_to_const<T>是什么具体类型(因为T),不到最后(当ptr_to_const<T>)被具象化
无法确切知道它是什么.更明确的说没办法知道它是不是有一个ap成员.

并且父类ptr_to_const可能会有被特化的可能,而那个特化的版本里面的确没有ap这个成员,这个时候较严谨的g++编译器就拒绝引用ap成员了.

书中还有一个例子来详细的说明为什么,具体看书吧.


总体解决方法:
1.Pointer类中加入
using ptr_to_const<T>::ap;
using ptr_to_const<T>::sub;
来让这两个变量可见
2.使用this指针引用成员
3.加上父类名ptr_to_const<T>::来引用成员

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值