c++虛擬函式實現計算表示式子
c++虛擬函式實現計算表示式
簡單的運算直接用運算子計算當然是簡單的
但是如果在一個表示式中,每一步的運算都很複雜呢?
並且還需要隨時新增複雜的表示式呢?
直接用運算子來構造就顯得有些冗雜了吧,也很不方便修改。
於是我們可以構造虛擬函式來解決這樣的問題
為了方便表達,我們這裡舉一個這樣的例子:
( ( 1 + 2 ) × 3 + 4 ) ÷ 6 \left( \left( 1+2\right) \times 3+4\right) \div 6 ((1+2)×3+4)÷6
雖然比較簡單,但是能體現大致的思想。
我們把它寫成樹,每個root都是一個運算方法。
如圖所示:
每一個節點的運算引數要麼是常數(此處我們叫做 TerminalExpression),要麼是表示式(可能是 AddExpression 也有可能是 Mutiplyexpression)。
由此我們想到可以用一個統一的函式去返回他們的值:
getvalue()
也就是說每一個的節點(運算)都可以當作一個派生類,而他們的 getvalue() 函式由該派生類中定義的兩個基類指標決定(由於基類指標可以指向派生類的物件!),派生類的物件型別由我們自己去輸入。
說到這裡可能有些雲裡霧裡,下面我們給出程式碼會更直觀一些:
#include<iostream>
#include<algorithm>
using namespace std;
class expression
{
public:
float value;
expression()
{
value = 0;
}
virtual float getvalue() = 0;
};
//所有的派生類(表示式)都有一個返回float型的getvalue()返回該基類派生類的value
class TerminalExpression: public expression
{
public:
virtual float getvalue()
{
return value;
}
};
class AddExpression: public expression
{
public:
expression* l; //基類的指標可以new派生類的物件!!!
expression* r;
virtual float getvalue()
{
value = l->getvalue() + r->getvalue();
return value;
}
};
class MultiplyExpression: public expression
{
public:
expression* l;
expression* r;
virtual float getvalue()
{
value = l->getvalue() * r->getvalue();
return value;
}
};
class DivisionExpression: public expression
{
public:
expression* l;
expression* r;
virtual float getvalue()
{
value = l->getvalue() / r->getvalue();
return value;
}
};
//((1 + 2)*3 + 4)/6 = 2.16667
int main()
{
AddExpression *p = new AddExpression;
p->l = new TerminalExpression;
p->l->value = 1;
p->r = new TerminalExpression;
p->r->value = 2; //左右兩側均為terminal賦值
MultiplyExpression *q = new MultiplyExpression;
q->l = new AddExpression;
q->l = p; //左側的值為表示式p
q->r = new TerminalExpression;
q->r->value = 3;
AddExpression *n = new AddExpression;
n->l = new MultiplyExpression;
n->l = q; //左側的值為表示式q
n->r = new TerminalExpression;
n->r->value = 4;
DivisionExpression *d = new DivisionExpression;
d->l = new AddExpression;
d->l = n; //左側的值表示式為n
d->r = new TerminalExpression;
d->r->value = 6;
cout<<d->getvalue()<<endl;
return 0;
}
在程式碼中可以直觀地看到,每一個運算是一個派生類,在main函式中是對其運算引數的賦值。
因此在main函式中,我們只需對每個運算的左引數和右引數進行賦值即可。
因此通過虛擬函式,我們可以輕易地增加運算,新增一個派生類即可,體現了C++對增添開放對修改封閉的特點。
其中最妙的地方在於基類指標可以new出派生類的物件,才能使該方法實現。
希望能和大家多多交流!
相關文章
- C++ 虛擬函式C++函式
- C++虛擬函式C++函式
- 虛擬函式表-C++多型的實現原理函式C++多型
- C++中抽象類、虛擬函式和純虛擬函式C++抽象函式
- C++中的虛擬函式與虛擬函式表 (轉)C++函式
- c++虛擬函式表C++函式
- C++虛擬函式bugC++函式
- 虛擬函式的實現原理函式
- 虛擬函式實現原理(轉)函式
- C++(虛擬函式實現多型基本原理)C++函式多型
- 【C++筆記】虛擬函式(從虛擬函式表來解析)C++筆記函式
- 【C++筆記】虛擬函式(從虛擬函式概念來解析)C++筆記函式
- C++ 介面(純虛擬函式)C++函式
- C++ 中的虛擬函式C++函式
- C++ 虛擬函式表剖析C++函式
- C++ 虛擬函式表解析C++函式
- 虛擬函式,虛擬函式表函式
- 虛擬函式 純虛擬函式函式
- MySQL5.7 虛擬列實現表示式索引MySql索引
- C++虛擬函式與多型實戰 (轉)C++函式多型
- C++多型(上)——虛擬函式、虛表C++多型函式
- C++多型之虛擬函式C++多型函式
- C++中虛擬函式的作用C++函式
- C++虛擬函式解析(轉載)C++函式
- 深入C++成員函式及虛擬函式表C++函式
- C++箴言:避免解構函式呼叫虛擬函式C++箴言函式
- C++ 虛擬函式和虛繼承淺析C++函式繼承
- 我對C++中虛擬函式、純虛擬函式在實現多型中作用的一點淺薄認識 (轉)C++函式多型
- 深度解讀《深度探索C++物件模型》之C++虛擬函式實現分析(一)C++物件模型函式
- 深度解讀《深度探索C++物件模型》之C++虛擬函式實現分析(二)C++物件模型函式
- 深度解讀《深度探索C++物件模型》之C++虛擬函式實現分析(三)C++物件模型函式
- C++虛擬函式學習總結C++函式
- C++繼承二之虛擬函式C++繼承函式
- C++ 繼承、多型、虛擬函式C++繼承多型函式
- C++中的虛擬函式(virtual function)C++函式Function
- C++:純虛擬函式與抽象類C++函式抽象
- C++ Daily 《3》----建構函式可否是虛擬函式C++AI函式
- 用虛擬函式實現事件驅動! (轉)函式事件