你幾乎肯定是指Bjarne Stroustrup在書The C++ Programming Language中討論的類型字段。這個上下文中的類型字段只是一個基類中的某種變量,它指示了它的子類的實際類型。這裏有一個例子:
class Pet
{
public:
enum PetType { Dog, Cat, Bird, Fish };
void ToString()
{
switch(type)
{
case Pet::Dog: std::cout << "Dog" << std::endl; break;
case Pet::Cat: std::cout << "Cat" << std::endl; break;
case Pet::Bird: std::cout << "Bird" << std::endl; break;
case Pet::Fish: std::cout << "Fish" << std::endl; break;
}
}
private:
PetType type; // A type field.
};
class Dog : public Pet
{
public:
Dog() { type = Dog; }
};
// And so on...
void Test(const Pet& p) { p.ToString(); }
int main()
{
Dog d;
Test(d);
return 0;
}
這是實現ToString()
方法一個非常脆弱的方式。每次需要添加派生類Pet
時,都需要更新PetType
枚舉和ToString()
方法。例如,如果我需要一個Turtle
子類,我需要做這些改變:
// ...
enum PetType { Dog, Cat, Bird, Fish, Tutle /* Added */};
void ToString(const Pet& p)
{
switch(p.type)
{
case Pet::Dog: std::cout << "Dog" << std::endl; break;
case Pet::Cat: std::cout << "Cat" << std::endl; break;
case Pet::Bird: std::cout << "Bird" << std::endl; break;
case Pet::Fish: std::cout << "Fish" << std::endl; break;
case Pet::Turtle: std::cout << "Turtle" << std::endl; break; // Added
}
}
// ...
class Turtle : public Pet
{
public:
Turtle() { type = Turtle; } // Added
};
試想一下,如果Pet
類有不僅僅是ToString()
更多的功能;維護成爲一場噩夢。這是很多需要更改的代碼,但重要的是,爲了有一個Turtle
類,我需要修改Pet
類。這意味着需要更多的測試,代碼審查等。這明顯違反了the open/closed principle。這就是爲什麼類型字段非常容易出錯的原因。
一個顯著優越的方法是使用virtual
功能:上面的代碼不需要額外enum
S或switch
聲明
class Pet
{
public:
virtual void ToString() = 0;
};
class Dog : public Pet
{
public:
virtual void ToString() { std::cout << "Dog" << std::endl; }
};
class Turtle : public Pet
{
public:
virtual void ToString() { std::cout << "Turtle" << std::endl; }
};
// And so on...
void Test(const Pet& p) { p.ToString(); }
int main()
{
Turtle t
// Will call Turtle::ToString(), even though
// Test() was only given a const Pet&
Test(t);
return 0;
}
注意。調用Pet::ToString()
將自動調用ToString()
的Dog
s,Cat
s等的正確實現,代碼少得多。我甚至不需要更改Pet
課程;假如已經定義了Pet
,我可以根據需要放入Turtle
類。
對於可能合法使用類型字段see this Stack Overflow question and the answers to that question。
你好,無論我多麼努力地嘗試,我都無法理解你的意思以及你想問什麼。你能否嘗試以更明瞭的方式重寫問題? – Lefteris 2012-02-05 05:39:04
這是一個有效的問題。如果您不明白OP要詢問什麼,請不要將其投票爲*不是真正的Q *或*非建設性的*,它不是它們中的任何一個。 – 2012-02-05 05:47:39
@AIs我沒有downvote OP。只是要求澄清他的問題,因爲我不明白他指的是什麼。無論如何,Silico的回覆似乎是OP所要求的。 不知道他們把這種做法稱爲類型字段 – Lefteris 2012-02-05 05:51:51