体验面向对象 计算器篇

 

刚开始看程杰大佬的《大话设计模式》

感觉以前真的是空学了面向对象

拿着面向对象的利器(C++) 去做一些面向过程的东西

(当然不是说面向过程不好)

看到计算器篇之后马上动手调试

结果本来以为很简单的东西让我纠结了两天

首先是思想

以前在书本上看过

面向对象的优点是

便于维护 便于更改

容易增加接口等等

从来没有体验过

结果自己设计

好家伙

设计了基类里面有一个虚函数

结果编译的时候发现了这么一个错误

undefined reference to vtable for XXX

第一次知道原来有虚函数的类里面会有vtable

一开始没网 又不是语法错误 纠结我半天

原来我在基类里面只声明了虚函数却没定义。。。

解决办法两钟

1是定义

2是纯虚函数

想想也对 我的基类里面有的是两个操作数

从现实的语义来说 并不需要实例(对象)

那就用纯虚函数吧

这一来 纯虚函数的继承又忘了 也怪C++学的不咋滴 又到处翻课本

等出了一个加法子类以后又傻眼了

虽然知道程老说写一个工厂类

不过肿么实现纯虚基类呢 又开始纠结

CSDN 就是牛人云集

找到了《大话设计模式》的C++实现版代码

http://download.csdn.net/source/1136752

里面的

COperation *oper;

oper=new AddOperation();

让我深受启发

指针啊万能的指针

重新翻课本看到这三句话

1 子类对象可以隐含转换为父类对象

   子 = 父

2 子类对象可以初始化父类引用

  父 &A = 子

3 子类对象地址(指针)可以转换为父类指针

 *父(指针) = *子(指针)

上面不就是用到第三条么!!!

看来纯虚函数是通过指针来实现的

学习了学习了

不过肿么实现又是问题

一个数据基类 和加减乘除各种运算子类

肿么在运算时选择哪个子类

多态肿么实现??

传说中的代码工厂?

第一次设计想把代码工厂再通过各种运算类继承下来

想想不好

为什么呢?

因为如果这么写的话 以后要是再增加开方幂等别的接口

这个代码工厂还有在继承他们而且代码工厂内部可能还要大换血

所以继承关系不是很好的选择

那就用依赖关系吧

╮(╯▽╰)╭ 问题又来了

 

one = OperationFactoryT::Operate(numA,numB,ch);

 

在我用上面这句的时候

编译器告诉我OperationFactoryT木有对象

坑爹啊!!!

都快写好了好不好

 

看看人家的代码吧

发现他的代码工厂类里有一个static

静态成员函数啊!!!

ok 编译通过 运行正确

╮(╯▽╰)╭

 

#include <iostream>

using std::cout;
using std::endl;
using std::cin;

class DataT
{
public:
 DataT();
 DataT(DataT &temp);
 double virtual Getresult()=0;
 void SetnumA(double temp);
 double GetnumA();
 void SetnumB(double temp);
 double GetnumB();
 virtual ~DataT()=0;
private:
 double _numberA;
 double _numberB;
};
DataT::DataT()
{
 _numberA = 0;
 _numberB = 0;
}
DataT::DataT(DataT &temp)
{
 _numberA = temp.GetnumA();
 _numberB = temp.GetnumB();
}
DataT::~DataT(){}
void DataT::SetnumA(double temp)
{
 _numberA = temp;
}
double DataT::GetnumA()
{
 return _numberA;
}
void DataT::SetnumB(double temp)
{
 _numberB = temp;
}

double DataT::GetnumB()
{
 return _numberB;
}


class AddT:public DataT
{
public:
 double Getresult();
};
double AddT::Getresult()
{
 double result = 0;
 result = GetnumA() + GetnumB();
 return result;
}

class SubT:public DataT
{
public:
 double Getresult();
};
double SubT::Getresult()
{
 double result = 0;
 result = GetnumA() - GetnumB();
 return result;
}

class MulT:public DataT
{
public:
 double Getresult();
};
double MulT::Getresult()
{
 double result = 0;
 result = GetnumA() * GetnumB();
 return result;
}

class DivT:public DataT
{
public:
 double Getresult();
};
double DivT::Getresult()
{
 double result = 0;
 result = GetnumA() / GetnumB();
 return result;
}

class OperationFactoryT
{
public:
 static DataT* Operate(double numA, double numB, char ch);
};

DataT* OperationFactoryT::Operate(double numA, double numB, char ch)
{
 DataT* temp;
 switch(ch)
 {
  case '+':
   temp = new AddT();
   break;
  case '-':
            temp = new SubT();
            break;
  case '*':
            temp = new MulT();
            break;
  case '/':
            temp = new DivT();
            break;
        default:
            cout << "输入错误" << endl << endl;
            break;
 }
 temp->SetnumA(numA);
 temp->SetnumB(numB);
 return temp;
}

int main()
{

    double numA, numB;
    char ch;
    while(cin >> numA >> ch >> numB)
 {
 DataT* one;
 one = OperationFactoryT::Operate(numA,numB,ch);
    cout << one->Getresult() << endl;
 }
 return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值