- 浏览: 497038 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jkxydp:
算法运行的结果根本就不对。
BM算法. -
soarwindzhang:
感谢博主的分享,我今天看了您的UFSET非递归的路径压缩时感觉 ...
并查集 -
zhangning290:
楼主好像只考虑了坏字符规则,。没有考虑好后缀
BM算法. -
lsm0622:
文字描述有错误 误导新学者
求有向图的强连通分量(scc):Tarjan算法 -
knightchen:
博主,你太强了!这篇文章对我学习C++多线程很有帮助!谢谢
并发学习之一_windows下ZThread在CodeBlocks上的安装与配置
1,多继承带来的一个根本性的复杂性:模棱两可.
例如:
注:纵使其中一个继承的draw函数时private属性,依旧模棱两可.
原因:"存取限制"不能解除"因多继承而得之members"的模棱两可状态.
理由:改变某个class成员的可存取性,绝不应该连带改变程序的意义.
2,即使这么改了,依旧存在问题:
3,一个绕弯的解决方法:
#include <iostream>
using namespace std;
class Lottery
{
public:
virtual void draw() { cout << "Lottery" << endl; }
};
class GraphicalObject
{
public:
virtual void draw() { cout << "GraphicalObject" << endl; }
};
class AuxLottery: public Lottery
{
public:
virtual void lotteryDraw() = 0;
virtual void draw() { lotteryDraw(); }
};
class AuxGraphicalObject: public GraphicalObject
{
public:
virtual void graphicalObjectDraw() = 0;
virtual void draw() { graphicalObjectDraw(); }
};
//注:这两个函数的作用就是为继承而来的draw函数声明一个新名称.
class LotterySimulation: public AuxLottery, public AuxGraphicalObject
{
public:
virtual void lotteryDraw() { cout << "Lottery Part." << endl; }
virtual void graphicalObjectDraw() { cout << "GraphicalObject Part." << endl; }
};
int main()
{
LotterySimulation *pls = new LotterySimulation;
Lottery *pl = pls;
GraphicalObject *pgo = pls;
pl->draw(); // this calls LotterySimulation::lotteryDraw
pgo->draw();// this calls LotterySimulation::graphicalObjectDraw
return 0;
}
4,看下面这个"钻石"
如果你不希望D对象内含多份A成员,那么上述的B和C都将A声明为一个virtual base class.
当A是一个nonvirtual base时,D对象的典型内存布局:
当A是一个virtual base时,D对象的典型内存布局,其中内含两个指针:
5,当virtual base class需要引用计数时:
引用计数被指定于这一base派生类最深的classes的成员初值表.
最简单的办法:避免virtual base classes拥有data成员.
看下面的例子:
A定义了虚拟函数mf(),C重新定义了mf,B和D没有重新定义mf.
D调用哪个mf?直接继承自C的那个,还是间接调用A的那个.
答案:
如果A是B或C的nonvirtual基类,上述调用模棱两可.
如果是virtual基类:调用C::mf.
6,实用:如果你可以避免实用virtual base(避免"钻石"继承),事情会好处理得多.
看一个实例:
class PersonInfo //利用它的实现,private inheritance
{
public:
PersonInfo(DatabaseID pid);
virtual ~PersonInfo();
virtual const char * theName() const;
virtual const char * theBirthDate() const;
virtual const char * theAddress() const;
virtual const char * theNationality() const;
virtual const char * valueDelimOpen() const; // see
virtual const char * valueDelimClose() const; // below
};
const char * PersonInfo::valueDelimOpen() const
{
return "["; // default opening delimiter
}
const char * PersonInfo::valueDelimClose() const
{
return "]"; // default closing delimiter
}
class Person //利用它的接口:public inheritance
{
public:
virtual ~Person();
virtual string name() const = 0;
virtual string birthDate() const = 0;
virtual string address() const = 0;
virtual string nationality() const = 0;
};
class MyPerson: public Person, private PersonInfo // multiple inheritance
{
public:
MyPerson(DatabaseID pid): PersonInfo(pid) {}
//虚函数,重新定义
const char * valueDelimOpen() const { return ""; }
const char * valueDelimClose() const { return ""; }
// 重用PersonInfo的实现
string name() const
{ return PersonInfo::theName(); }
string birthDate() const
{ return PersonInfo::theBirthDate(); }
string address() const
{ return PersonInfo::theAddress(); }
string nationality() const
{ return PersonInfo::theNationality(); }
};
例如:
#include <iostream> using namespace std; class Lottery { public: virtual void draw() { cout << "Lottery" << endl; } }; class GraphicalObject { public: virtual void draw() { cout << "GraphicalObject" << endl; } }; class LotterySimulation: public Lottery, public GraphicalObject //多重继承 { // doesn't declare draw }; int main() { LotterySimulation *pls = new LotterySimulation; //pls->draw(); // 模棱两可 pls->Lottery::draw(); // fine pls->GraphicalObject::draw(); // fine return 0; }
注:纵使其中一个继承的draw函数时private属性,依旧模棱两可.
原因:"存取限制"不能解除"因多继承而得之members"的模棱两可状态.
理由:改变某个class成员的可存取性,绝不应该连带改变程序的意义.
2,即使这么改了,依旧存在问题:
#include <iostream> using namespace std; class Lottery { public: virtual void draw() { cout << "Lottery" << endl; } }; class GraphicalObject { public: virtual void draw() { cout << "GraphicalObject" << endl; } }; class LotterySimulation: public Lottery, public GraphicalObject //多重继承 { // doesn't declare draw }; class SpecialLotterySimulation: public LotterySimulation { public: virtual void draw() { cout << "SpecialLotterySimulation" << endl; } }; int main() { LotterySimulation *pls = new SpecialLotterySimulation; //pls->draw(); // 依旧模棱两可 pls->Lottery::draw(); // fine pls->GraphicalObject::draw(); // fine return 0; }
3,一个绕弯的解决方法:
#include <iostream>
using namespace std;
class Lottery
{
public:
virtual void draw() { cout << "Lottery" << endl; }
};
class GraphicalObject
{
public:
virtual void draw() { cout << "GraphicalObject" << endl; }
};
class AuxLottery: public Lottery
{
public:
virtual void lotteryDraw() = 0;
virtual void draw() { lotteryDraw(); }
};
class AuxGraphicalObject: public GraphicalObject
{
public:
virtual void graphicalObjectDraw() = 0;
virtual void draw() { graphicalObjectDraw(); }
};
//注:这两个函数的作用就是为继承而来的draw函数声明一个新名称.
class LotterySimulation: public AuxLottery, public AuxGraphicalObject
{
public:
virtual void lotteryDraw() { cout << "Lottery Part." << endl; }
virtual void graphicalObjectDraw() { cout << "GraphicalObject Part." << endl; }
};
int main()
{
LotterySimulation *pls = new LotterySimulation;
Lottery *pl = pls;
GraphicalObject *pgo = pls;
pl->draw(); // this calls LotterySimulation::lotteryDraw
pgo->draw();// this calls LotterySimulation::graphicalObjectDraw
return 0;
}
4,看下面这个"钻石"
如果你不希望D对象内含多份A成员,那么上述的B和C都将A声明为一个virtual base class.
当A是一个nonvirtual base时,D对象的典型内存布局:
当A是一个virtual base时,D对象的典型内存布局,其中内含两个指针:
5,当virtual base class需要引用计数时:
引用计数被指定于这一base派生类最深的classes的成员初值表.
最简单的办法:避免virtual base classes拥有data成员.
看下面的例子:
A定义了虚拟函数mf(),C重新定义了mf,B和D没有重新定义mf.
D调用哪个mf?直接继承自C的那个,还是间接调用A的那个.
答案:
如果A是B或C的nonvirtual基类,上述调用模棱两可.
如果是virtual基类:调用C::mf.
6,实用:如果你可以避免实用virtual base(避免"钻石"继承),事情会好处理得多.
看一个实例:
class PersonInfo //利用它的实现,private inheritance
{
public:
PersonInfo(DatabaseID pid);
virtual ~PersonInfo();
virtual const char * theName() const;
virtual const char * theBirthDate() const;
virtual const char * theAddress() const;
virtual const char * theNationality() const;
virtual const char * valueDelimOpen() const; // see
virtual const char * valueDelimClose() const; // below
};
const char * PersonInfo::valueDelimOpen() const
{
return "["; // default opening delimiter
}
const char * PersonInfo::valueDelimClose() const
{
return "]"; // default closing delimiter
}
class Person //利用它的接口:public inheritance
{
public:
virtual ~Person();
virtual string name() const = 0;
virtual string birthDate() const = 0;
virtual string address() const = 0;
virtual string nationality() const = 0;
};
class MyPerson: public Person, private PersonInfo // multiple inheritance
{
public:
MyPerson(DatabaseID pid): PersonInfo(pid) {}
//虚函数,重新定义
const char * valueDelimOpen() const { return ""; }
const char * valueDelimClose() const { return ""; }
// 重用PersonInfo的实现
string name() const
{ return PersonInfo::theName(); }
string birthDate() const
{ return PersonInfo::theBirthDate(); }
string address() const
{ return PersonInfo::theAddress(); }
string nationality() const
{ return PersonInfo::theNationality(); }
};
发表评论
-
条款44:说出你的意思并了解你所说的每一句话
2010-06-08 09:30 7741,彻底了解不同的面向对象架构在C++中的意义. 2,声明一 ... -
条款30:避免写出member function,传回一个non-const function或reference并指向private或protect成员
2010-06-08 09:29 11891,先看一个例子: class Address { ... } ... -
条款4:尽量使用C++风格的注释形式
2010-06-07 09:49 7121,抛弃"/*...*/",改用" ... -
条款39:避免在继承体系中做向下转型(downcast)动作
2010-06-01 10:37 14381,先看个例子: class Person { ... }; ... -
条款2:尽量以<iostream>取代<stdio.h>
2010-06-01 10:36 9751,scanf和printf的缺点:不具有型别安全(type- ... -
条款1:尽量以const和inline取代#define
2010-06-01 10:35 9171,意思就是"尽量以编译器(compiler)&qu ... -
条款42:明智地使用private inheritance(私有继承)
2010-05-29 17:51 9511,先搞清楚private inheritance的行为: ( ... -
条款41:区分inheritance和template
2010-05-29 17:50 6671,首先考虑一个问题: 型别T会影响class的行为吗? 如果 ... -
条款40:通过layering技术来模塑"有一个"(has-a)或"根据某物实现(is-implemented-in-terms-of)"
2010-05-29 17:48 7611,所谓laying,就是以一个class为本,建立另外一个c ... -
条款38:绝对不要重新定义继承而来的缺省参数值
2010-05-29 17:48 7841,首先可以安全的把问题讨论局限于"继承一个带有缺省 ... -
条款37:绝对不要重新定义继承而来的非虚拟函数
2010-05-29 17:47 7271,先看个例子: class B { public: vo ... -
条款36:区分接口继承和实现继承
2010-05-29 17:46 8451,public继承分为两类:接口继承和实现继承. 这两种继承 ... -
条款35:确定你的public继承,模塑出"isa"的关系
2010-05-29 17:46 9541,C++面向对象程序设计最重要的原则: public继承意味 ... -
条款29:避免传回内部数据的handles
2010-05-28 10:35 13471,考虑下面的代码: class string { oper ... -
条款28:尝试切割global namesapce
2010-05-28 10:34 6811,namesapce的使用 namespace std{ ... -
条款50:加强自己对C++的了解
2010-05-25 11:46 8721,只推荐两本书: (1)D&E: The Desig ... -
条款49:尽量让自己熟悉C++标准库
2010-05-25 11:46 7781,标准库的每一样东西几乎都在namespace std中,然 ... -
条款48:不要对编译器的警告视而不见
2010-05-25 11:45 7681,在你忽略一个警告之前,你必须精确了解编译器企图告诉你的是什 ... -
条款47:使用non-local static objects之前先确定它已有初值
2010-05-25 11:45 8281,当一个编译单元内某对象的初始化动作,与另一个编译单元内某对 ... -
条款26:防卫潜伏的ambiguity状态
2010-05-25 11:44 7251, class B; class A { public: ...
相关推荐
条款43: 明智地使用多继承 条款44: 说你想说的;理解你所说的 第七章 杂项 条款45: 弄清C++在幕后为你所写、所调用的函数 条款46: 宁可编译和链接时出错,也不要运行时出错 条款47: 确保非局部静态对象在使用前被...
条款43:明智的使用多继承 条款44:说你想说的,理解你说的 6、杂项 条款45:弄清C++在幕后为你所写、所调用的函数 条款46:宁可编译与链接时出错,也不要运行时出错 条款47:确保非局部静态对象在使用前被初始化 条款48:...
条款43:学习处理模板化基类内的名称 know how to access names in templatized base classes. 条款44:将与参数无关的代码抽离templates factor parameter-independent code out of templates. 条款45:运用成员...
内容简介: 有人说C++程序员可以分成两类,读...条款39:明智而审慎地使用private继承 条款40:明智而审慎地使用private继承 7.模板与泛型编程 8.定制new和delete 9.杂项讨论 A 本书之外 B 新旧版条款对映 索引
《exceptional c++:47个c++工程难题、编程问题和解决方案(中文版)》...条款43:正确使用const 222 条款44:类型转换 231 条款45:bool 238 条款46:转调函数 242 条款47:控制流程 244 后记 254 参考书目 256
条款43: 尽量用算法调用代替手写循环 条款44: 尽量用成员函数代替同名的算法 条款45: 注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46: 考虑用函数对象代替函数作为算法的...
条款43:尽量用算法调用代替手写循环 条款44:尽量用成员函数代替同名的算法 条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46:考虑使用函数对象代替函数作算法的...
·条款九:使用析构函数防止资源泄漏 ·条款十:在构造函数中防止资源泄漏 ·条款十一:禁止异常信息(exceptions)传递到析构函数外 ·条款十二:理解“抛出一个异常”与“传递一个参数”或“调用一...
条款43: 尽量用算法调用代替手写循环 条款44: 尽量用成员函数代替同名的算法 条款45: 注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46: 考虑用函数对象代替函数作为算法的...
fun、mem_fun和mem_fun_ref的原因 条款42:确定less表示operator使用STL编程 条款43:尽量用算法调用代替手写循环 条款44:尽量用成员函数代替同名的算法 条款45:注意count、find、binary_search、...
条款14:明智运用 exception specifications 072 Use exception specifications judiciously 条款15:了解异常处理(exception handling)的成本 078 Understand the costs of exception handling 效率(Efficiency...
ROHS豁免条款:ROHS豁免项清单及ROHS最新豁免条例.pdf
条款7: 当使用new得指针的容器时,切记在容器销毁前delete那些指针 条款8: 千万不要把auto_ptr放入容器中 条款9: 小心选择删除选项 条款10: 当心allocator的协定和约束 条款11: 了解自定义allocator的正统使用法...
ISO9001:2015标准条款测试题参考答案.pdf
Effective Modern C++英文版及中文翻译. 第一章 类型推导 条款1: 理解模板类型推导 条款2: 理解auto类型推导 条款3: 理解decltype ...条款6: 当auto推导出非预期类型时应当使用显式的类型初始化
App.net 服务条款App.net 服务条款文件位于此处。 为了促进透明的讨论,我们鼓励用户根据您的反馈创建问题和/或提交拉取请求。 我们的一般流程是根据与我们的法律团队的审查,大约每季度纳入一次用户反馈,但在早期...
公交服务采购的激励合同和质量条款:以智利圣地亚哥为例-word资料.pdf
使用条款 编写的代码的使用条款。本文档包含将Loki或其开发团队的任何机器人添加到服务器或使用Internet上可用的代码时接受的使用条款和协议。本文档不取代以下任何内容: 适用于 使用条款始终适用于: 下的所有...
目 录一.让自己习惯 C++ 1条款 03:尽可能使用 const 23)const 修饰成员函数 2条款 04:确定对象被使用前已先被初始化 4二.构造/析构
阿里巴巴内部使用条款