[操作疑難] C++ Virtual 問題

Rectangle 有無可能唔 Override draw 嘅情況下,
可以 Call 得到 Screen::drawShape(Rectangle*) ?

class Shape {
    public:
        virtual void draw ( Screen* scr ) {
              scr -> drawShape ( this );
       }
}

class Rectangle:public Shape { }

class Screen {
    public:
       void drawShape ( Shape *s ) {
            cout << "Draw Shape" ;
       }

       void drawShape ( Rectangle *r ) {
            cout  << "Draw Rectangle" ;
       }
}

本帖最後由 it_jobs 於 2021-4-1 09:51 編輯
我個諗法係每個 Shape define 出嚟嗰陣,
有自己嘅 Generic 方法處理 Draw。

當 Screen 無自己方法處理呢 ...
ghostkcleung 發表於 2021-3-31 19:38


如果我個寫法.  你新 class 只要唔寫多個 ObjDraw() method, 就自然 call base ObjDraw().
利申, 個方法應該係唔知邊到睇返黎, 應該唔係我發明, 寫住"我個寫法"只係講我帶出黎.

//--------------------------------------------------
// Circle.h
//--------------------------------------------------
#include "Shape.h"

class Circle : public Shape
{
};

//--------------------------------------------------
// test.cpp
//--------------------------------------------------
#include <iostream>
#include "DevToolBox.h"

#include "Rect.h"
#include "Circle.h"

using namespace std;

int main()
{
    cout << "In " << __METHOD_NAME__ << endl;
    Rect *rect = new Rect();
    rect->Draw();

    Circle circle;
    cout << "Drawing Circle begin" << endl;
    circle.Draw();
    cout << "Drawing Circle end" << endl;

    return 0;
}


//--------------------------------------------------
//  Console output
//--------------------------------------------------
$ ./test
In main()
In Shape::Draw()
In Shape::PreDraw()
In Rect::ObjDraw()
In Shape::PostDraw()
Drawing Circle begin
In Shape::Draw()
In Shape::PreDraw()
In Shape::ObjDraw()
In Shape::PostDraw()
Drawing Circle end

TOP

我個諗法係每個 Shape define 出嚟嗰陣,
有自己嘅 Generic 方法處理 Draw。

當 Screen 無自己方法處理呢 ...
ghostkcleung 發表於 2021-3-31 19:38


即係講緊M款Screen + N款Shape = M x N

我個人會咁做:
Shape <-- GenericShape <-- Triangle/Rectangle

有咩Generic既放去中間果層class handle, 獨立唔同既就放去最child
日後加Screen的話, 可以先去GenericShape果度加翻D fallback code先

TOP

我個諗法係每個 Shape define 出嚟嗰陣,
有自己嘅 Generic 方法處理 Draw。

當 Screen 無自己方法處理呢個 Shape 嗰陣,
就會用 Shape 嘅 Generic;

如果將來有新嘅 Screen,
對 Shape 有自己獨特處理方法,
亦有自己嘅 Override Draw。

TOP

[quote]原本個佈局大約係咁樣…

class Shape {
  void draw(Screen *scr) { scr->drawShape (this); }
  virtual  ...
[size=2][color=#999999]ghostkcleung 發表於 2021-3-30 20:39[/color] [url=https://www.hkepc.com/forum/redirect.php?goto=findpost&pid=40253574&ptid=2613236][img]//i.hkepc.net/forum/common/back.gif[/img][/url][/size][/quote]

試想一下, 如果 drawShape 點用.

A)
Screen s;
Circle c;
c.drawShape()?

Shape[] shapeList = {...};
for(int i =0; i < sizeof(shapeList)/sizeof(shapeList[0]); i++) {
   shapeList\[i\].drawShape();
}

B)
Screen s;
Circle c;
c.drawShape(&c); // or
s.drawShape(&c);

Shape[] shapeList = {...};
for(int i =0; i < sizeof(shapeList)/sizeof(shapeList[0]); i++) {
   s.drawShape(shapeList[i]);
}

正常別一位師兄話齋.
如果 Shape 要包山包海, 咁當有粒沙新生出黎, 你就要改 shape 嘅 code, 去對應新 shape 嘅 drawing.
個新shape 由邊個 define, 入面個 logic 係點做, 邊個知呢?
假設唔係1 man band, 有人負責 shape base class, 有人負責起新 shape. 咁就要起新 shape 嘅人向 shape base class owner 要求改變.  好似怪怪地.
又有個問題係, 當同時起幾個新 shape, 大家都要衝去改 base class, 又好似制造不必要嘅 merge problem.

TOP

本帖最後由 it_jobs 於 2021-3-31 16:13 編輯
但都係分唔到 Type 。
ghostkcleung 發表於 2021-3-30 20:27


我懶啫

//----------------------------------
//  test.cpp
//----------------------------------
#include "Rect.h"
#include <iostream>

using namespace std;

int main()
{
    cout << "CPP Test...." << endl;
    Rect *rect = new Rect();
    rect->Draw();
    return 0;
}

//----------------------------------
// Sharp.h
//----------------------------------
class Sharp
{
public:
    virtual void Draw();
    char name[200] = "Sharp";

public:
    virtual void PreDraw();
    virtual void ObjDraw();
    virtual void PostDraw();
};

//----------------------------------
// Sharp.cpp
//----------------------------------
#include <iostream>
#include "Sharp.h"

using namespace std;

void Sharp::PreDraw()
{
    cout << "In Parent PreDraw" << endl;
}

void Sharp::ObjDraw()
{
    cout << "In Parent ObjDraw" << endl;
}

void Sharp::PostDraw()
{
    cout << "In Parent PostDraw" << endl;
}

void Sharp::Draw()
{
    cout << "In Parent Draw" << endl;
    this->PreDraw();
    this->ObjDraw();
    this->PostDraw();
}

//----------------------------------
// Rect.h
//----------------------------------
#include "Sharp.h"

class Rect : public Sharp
{
public:
    virtual void ObjDraw();
};

//----------------------------------
// Rect.cpp
//----------------------------------
#include <iostream>
#include "Rect.h"

using namespace std;
void Rect::ObjDraw()
{
    cout << "In Rect::ObjDraw" << endl;
}

//----------------------------------
// Console output
//----------------------------------
CPP Test....
In Parent Draw
In Parent PreDraw
In Rect::ObjDraw
In Parent PostDraw

TOP

OO 而言,到明日有新Shape... say "Star".. 今日點會知Star::Draw點implement? 唔係叫迫住要copy, 係想model "Star"成為一個Shape,就要be a Shape

TOP

本帖最後由 ghostkcleung 於 2021-3-30 22:02 編輯

我諗法係,將來如果有新嘅 Shape,
我唔須要搞個 Screen。
又如果我有新嘅 Screen,
對 Shape 有自己獨特嘅 draw 法,
可以直接 Override,
亦唔須要去搞啲 Shape。

但依家無辦法做呢樣嘢。

TOP

本帖最後由 ghostkcleung 於 2021-3-31 19:41 編輯

原本個佈局大約係咁樣…

class Shape {
  void draw(Screen *scr) { scr->drawShape (this); }
  virtual void draw Generic(Screen *scr)=0;
};

class Rectangle : public Shape {
  void drawGeneric(Screen scr) {
     cout << "Rectangle" << end;
  }
}

class Circle : public Shape {
  void drawGeneric(Screen scr) {
     cout << "Circle" << end;
  }
}

class Screen {
  void drawShape(Shape *s) {
    s->drawGeneric(this);
  }
}

Class SubScreen {
  void drawShape(Rectangle *r){
     cout << "won't be called";
  }
}

TOP

但都係分唔到 Type 。

有幾大重覆性先?

可否
draw() {
predraw();
drawSharp();
postdraw();
}

predraw(), postdraw()  ...
it_jobs 發表於 2021-3-30 10:00

TOP