构造函数虚化:
- NewsLetter构造函数,能根据不同数据建立不同类型的对象,行为与构造函数相似;
class NLComponent {};
class TextBlock: public NLComponent {};
class Graphic: public NLComponent {};
class NewsLetter {
public:NewsLetter(std::istream& str) {while (str) {components.push_back(readNLComponent(str));}}
private:std::list<NLComponent*> components;static NLComponent* readNLComponent(std::istream& str);
};
拷贝构造函数虚化:
- NewsLetter拷贝构造函数,能根据不同类型的对象,行为与拷贝构造函数相似;
- 虚拟拷贝构造返回一个指针,只想调用调用该函数对象的新拷贝;
class NLComponent {
public:virtual NLComponent* clone() const = 0;
};
class TextBlock: public NLComponent {
public:virtual TextBlock* clone() const {return new TextBlock(*this);}
};
class Graphic: public NLComponent {
public:virtual Graphic* clone() const {return new Graphic(*this);}
};
class NewsLetter {
public:NewsLetter(std::istream& str) {while (str) {components.push_back(readNLComponent(str));}}NewsLetter(const NewsLetter& rhs) {for (auto it = rhs.components.begin(); it != rhs.components.end(); ++it) {components.push_back((*it)->clone());}}
private:std::list<NLComponent*> components;static NLComponent* readNLComponent(std::istream& str);
};
非成员函数虚化:
-
如果以成员函数的方式重载operator<<,得把cout放到<<符号的右边,与一般用法相反;
-
另一种方法是声明虚拟函数和重载 operator<<非成员函数,该非成员函数只调用虚拟函数;
class NLComponent {
public:virtual std::ostream& operator<<(std::ostream& str) const = 0;
};
class TextBlock: public NLComponent {
public:virtual std::ostream& operator<<(std::ostream& str) const {str << "Output TextBlock information here!\n";return str;}
};
class Graphic: public NLComponent {
public:virtual std::ostream& operator<<(std::ostream& str) const {str << "Output Graphic information here!\n";return str;}
};int main() {TextBlock t;t << std::cout;return 0;
}
class NLComponent {
public:virtual std::ostream& print(std::ostream& str) const = 0;
};
class TextBlock: public NLComponent {
public:virtual std::ostream& print(std::ostream& str) const {str << "Output TextBlock information here\n";return str;}
};
class Graphic: public NLComponent {
public:virtual std::ostream& print(std::ostream& str) const {str << "Output Graphic information here\n";return str;}
};
inline
std::ostream& operator<<(std::ostream& s, const NLComponent& c) {return c.print(s);
}
int main() {TextBlock t;std::cout << t;return 0;
}