构造函数虚化:
- 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;
}