2015-05-03 10 views
-1

我知道OOP的所有理論,但有些東西我不明白。假設,我有一個vector3D類,它有3個變量(3個座標)以及一些計算長度和內容的操作。在我的例子的實踐中的幾個C + +繼承問題?

現在我想要構建一個Vector2D類,它將繼承自Vector3D,畢竟它與第三個座標等於0相同,現在我該怎麼做?我該如何編寫Vector2D的構造函數,它將構建一個vector3D,其第三個座標等於0?

如果我將座標設爲private,那麼我如何繼承它們並將它們用作Vector2D的座標,或者即使使它們受到保護,這是否意味着vector2D將擁有它自己的單獨座標?

+1

繼承模型是「是 - 一個」關係(例如狗是「動物」)。所有的2D矢量也是3D矢量嗎? – Barry

+9

'我知道*所有* OOP的理論'非常有趣。 – deviantfan

+1

通常這不是使用繼承完成的,特別是不以_reverse_方式。這是對模板的呼籲。 –

回答

2

下面的代碼將實現你所描述的:

class Vector3D { 
public: 
    Vector3D(int x, int y, int z) : x_(x), y_(y), z_(z) { } 
    virtual ~Vector3D() = default; 
    int get_x() { return x_; } 
    int get_y() { return y_; } 
    int get_z() { return z_; } 
    // ... other member functions ... 
private: 
    int x_, y_, z_; 
}; 

class Vector2D : public Vector3D { 
public: 
    Vector2D(int x, int y) : Vector3D(x, y, 0) { } 
    virtual ~Vector2D() = default; 
}; 

中的Vector3D定義的所有成員函數將提供給類型的Vector2D的對象。這也意味着,在此實現中,您可以在Vector2D類型的對象上調用get_z()

Vector2D v2d(5, 7); 
int z = v2d.get_z(); // z will be 0 

這可能不是你想要的。如果這是你想要的,太棒了!但也考慮到這一點:

Vector3D* ptr = new Vector2D(8, 3); 

該代碼是合法的,你也想讓這種情況發生?

順便說一句,從繼承的Vector3D的Vector2D如果你想的Vector2D對象表現得像的Vector3D對象是必需的:

#include <vector> 
std::vector<Vector3D*> v; 
v.push_back(new Vector3D(1, 2, 3)); 
v.push_back(new Vector2D(4, 5)); // Legal because Vector2D inherits from Vector3D 

v[0]->get_z(); // = 3 
v[1]->get_z(); // = 0 

旁註:從不使用原始指針在生產代碼,使用std::shared_ptr<Vector3D>代替!

如果這個實施是好的取決於您的需求,並且由您決定。它既有優點也有缺點。


爲了回答您的其他問題:

我怎樣寫的Vector2D的構造函數將建立的Vector3D與第三座標等於零?

您需要使用initialization lists從基類調用特定的構造函數:

#include <iostream> 

class Base { 
public: 
    Base(int i) { 
     std::cout << "Base ctor with " << i << "\n"; 
    } 
}; 

class Derived : public Base { 
public: 
    Derived(int i, int j) : Base(i) { // Calls Base's constructor with argument 'i' 
     std::cout << "Derived ctor with " << i << " and " << j << "\n"; 
    } 
}; 

int main(int argc, char** argv) { 
    Derived d(1, 2); 
    return 0; 
} 

編譯並運行:

$ Base ctor with 1 
$ Derived ctor with 1 and 2 

初始化對象的初始化列表裏將確保他們各自的構造函數首先被調用。


如果我做的座標私人我該如何繼承和使用它們作爲的Vector2D的座標,或者即使我讓他們保護將會是不是意味着會的Vector2D有它自己獨立的座標?

private成員只能從類內部訪問。要允許派生類訪問它們,您需要使它們成爲protected(或public,但這會讓所有人都可訪問!)。

class Base { 
protected: 
    int touch_me; 
private: 
    int cant_touch_me; 
}; 

class Derived : public Base { 
public: 
    void foo() { 
     int touch_me = 0; // Legal. 
     int cant_touch_me = 1; // Illegal, will result in a compile error. 
    } 
private: 
    int lonely; 
}; 

型基地的所有對象將有兩個數據成員:touch_mecant_touch_me

Derived類型的所有對象都有三個數據成員:touch_mecant_touch_melonely。由Derived聲明和實現的函數將只能訪問touch_melonely,但該對象確實包含全部三個!

+0

二維向量*可以*具有'z'維度;它通常是零,有時是不變的。 –

+0

@DonLarynx我認爲OP不希望Vector2D具有可訪問的第三維。我糾正了我的答案。 –