当前位置: 首页 > news >正文

建设银行网站登录不上去wordpress 搜索类似淘宝

建设银行网站登录不上去,wordpress 搜索类似淘宝,富平做网站,网络服务提供者是不是网络运营者文章目录1、对象的浅复制2、构造函数中的操作符重载3、拷贝构造函数不能模板化4、析构函数未捕获异常导致coredump5、构造函数抛出异常6、基类析构函数非虚导致内存泄漏7、删除void*指针引发内存泄露8、成员函数尾部缺失const9、使用memset初始化class10、对象向下转换失败1、对… 文章目录1、对象的浅复制2、构造函数中的操作符重载3、拷贝构造函数不能模板化4、析构函数未捕获异常导致coredump5、构造函数抛出异常6、基类析构函数非虚导致内存泄漏7、删除void*指针引发内存泄露8、成员函数尾部缺失const9、使用memset初始化class10、对象向下转换失败 1、对象的浅复制 class IntList { public:static const int SIZE 10;int *items;int numItems;int arraySize; public:IntList() {cout new[] endl;items new int[SIZE];items[0] 10;numItems 0;arraySize SIZE;}~IntList() {cout delete[] endl;items[0] 0;items nullptr;delete[] items;} // IntList operator(const IntList old) { // cout operator endl; // this-numItems old.numItems; // this-arraySize old.arraySize; // memcpy(this-items, old.items, sizeof(int)* this-numItems); // return (*this); // } };int main() {IntList* list1 new IntList();IntList list2; // 不能写成IntList list2 *list1; 否则不会调用赋值重载而是会调用拷贝构造list2 *list1;cout before endl;cout list1-items endl;cout list1-items[0] endl;cout list2.items endl;cout list2.items[0] endl;delete list1;list1 nullptr;cout after endl;cout list2.items endl;cout list2.items[0] endl;return 0; } 打印结果 new[] new[] before 0xeb5e30 10 0xeb5e30 10 delete[] after 0xeb5e30 0 delete[]如果类中没有对“”操作符重载或没有提供赋值构造函数那么对象间的复制只是浅复制(shallow copy)浅复制的意思就是C只会对对象中的每个成员使用赋值运算符。当类很简单的时候如没有动态分配内存的情况浅复制不会出问题。但是如果其中一个类成员变量为指针变量并且指向动态分配的空间那么在赋值之后被赋值的对象的指针变量将会指向原对象动态分配的空间因此原对象被析构之后被赋值对象的指针就变成悬挂指针。如果我们在一个对象被析构的时候做出指针所指对象清零操作那被赋值的对象指针所指的值也会被清零。 正确做法应该是增加赋值重载将浅拷贝变成深拷贝 IntList operator(const IntList old) {cout operator endl;this-numItems old.numItems;this-arraySize old.arraySize;memcpy(this-items, old.items, sizeof(int)* this-numItems);return (*this);}然后打印结果 new[] new[] operator before 0xf15e30 10 0xf15e60 10 delete[] after 0xf15e60 10 delete[]2、构造函数中的操作符重载 这个问题和上面的问题有点相关问题一的操作符重载的时候我们返回的是一个对象的引用有没有想过为什么 假设我们新构造一个类然后operator不返回引用然后再增加一个拷贝构造函数 class myClass { private:int data; public:myClass() {data 0;}myClass(const myClass i) {cout copy construct endl;*this i; // 这里调用的operator}myClass operator(const myClass i) {cout operator endl;data i.data;return *this;}int get() {return data;}void put(int d) {data d;} };int main() {myClass first;first.put(10);myClass second(first);cout second.get() endl;return 0; }此时打印结果会进入死循环 copy construct operator copy construct operator ....在 C中如果一个函数返回值(非引用)时会生成一个匿名的临时变量并将函数返回值赋值给匿名的临时变量如果函数返回引用则不会生成临时变量。 在拷贝构造函数MyClass(const MyClass i_class)中两个对象赋值时会调用操作符重载函数。调用操作符重载函数后会生成临时变量并把操作符重载函数的返回值赋值给临时变量这个过程会再次调用构造函数MyClass(const MyClassi_class)和操作符重载函数……从而导致反复调用构造函数及操作符重载函数程序陷入死循环。 正确做法 只需把操作符重载函数的返回值类型改成返回引用类型即可。 class myClass { private:int data; public:myClass() {data 0;}myClass(const myClass i) {cout copy construct endl;*this i;}myClass operator(const myClass i) {cout operator endl;data i.data;return *this;}int get() {return data;}void put(int d) {data d;} };int main() {myClass first;first.put(10);myClass second(first);cout second.get() endl;return 0; } 打印结果 copy construct operator 103、拷贝构造函数不能模板化 模板化的构造函数永远不会被编译器当做拷贝构造函数来使用只会以转换构造函数的形式存在。因此要想自定义的拷贝构造函数生效就不能对其模板化。 templateunsigned int sizeclass myvector { private:int* _data; public:myvector() {cout new[] endl;_data new int[size];}~myvector() {cout delete[] endl;delete[] _data;}// 转换构造函数// 将templateunsigned int size1类型转换为 templateunsigned int sizetemplateunsigned int n_size myvector(const myvectorn_size other) {cout trans construct endl;_data new int[size];int i 0;for (; i size i n_size; i) {_data[i] other[i];}for(; i size; i) {_data[i] 0;}}// 模板化的拷贝构造 显然不调用这个 templateunsigned int nsize myvector(const myvectorsize other) {cout copy construct endl;_data new int[size];for (int i 0; i size ; i) {_data[i] other[i];}} // myvector(const myvector other) { // cout copy construct endl; // _data new int[size]; // for (int i 0; i size ; i) { // _data[i] other[i]; // } // }int operator[](int i) {return _data[i];}const int operator[](int i) const { // 表示成员函数隐含传入的this指针为const指针决定了在该成员函数中任意修改它所在的类的成员的操作都是不允许的return _data[i];} };int main() {myvector2 vector2;vector2[0] 1;vector2[1] 2;// 调用转换构造函数myvector3 vector3(vector2);for (int i 0; i 3; i) {cout vector3[i] ;}cout endl; // 1 2 0// 调用了默认的拷贝构造函数myvector3 other3(vector3);for (int i 0; i 3; i) {cout other3[i] ;}cout endl; // 1 2 0return 0; } 打印结果很显然由于默认拷贝构造只是单纯浅拷贝导致vector3和other3的成员指针变量_data指向同一片内存。模板类的析构函数先后对vector3和other3对象的成员data_进行delete导致 double free的内存错误。 new[] trans construct 1 2 0 1 2 0 delete[] delete[]正确的做法在模板类中加上拷贝构造函数 #include iostream #include stdio.h #include vectorusing namespace std;templateunsigned int sizeclass myvector { private:int* _data; public:myvector() {cout new[] endl;_data new int[size];}~myvector() {cout delete[] endl;delete[] _data;}// 转换构造函数// 将templateunsigned int size1类型转换为 templateunsigned int sizetemplateunsigned int n_size myvector(const myvectorn_size other) {cout trans construct endl;_data new int[size];int i 0;for (; i size i n_size; i) {_data[i] other[i];}for(; i size; i) {_data[i] 0;}}myvector(const myvector other) {cout copy construct endl;_data new int[size];for (int i 0; i size ; i) {_data[i] other[i];}}int operator[](int i) {return _data[i];}const int operator[](int i) const { // 表示成员函数隐含传入的this指针为const指针决定了在该成员函数中任意修改它所在的类的成员的操作都是不允许的return _data[i];} };int main() {myvector2 vector2;vector2[0] 1;vector2[1] 2;// 调用转换构造函数myvector3 vector3(vector2);for (int i 0; i 3; i) {cout vector3[i] ;}cout endl; // 1 2 0// 调用了拷贝构造函数myvector3 other3(vector3);for (int i 0; i 3; i) {cout other3[i] ;}cout endl; // 1 2 0return 0; } 打印结果不会造成内存泄漏 new[] trans construct 1 2 0 copy construct 1 2 0 delete[] delete[] delete[] TODO对于模板化的一些函数有点忘了怎么写了所以这里的copy construct可能存在错误但是就算没错也不会去调用它的。 4、析构函数未捕获异常导致coredump class Foo { private:bool flag; public:Foo() : flag(false) {}~Foo() {if (flag true) {cout throw Exception1 endl;throw Exception1;}}void set_flag(bool value) {flag value;} };int main() {try {bool unexpected_condition false;Foo foo;foo.set_flag(true);unexpected_condition true;if (unexpected_condition) {cout throw Exception2 endl;throw Exception2;}} catch(...) {cout Exception caught. endl;}return 0; }打印结果 terminate called after throwing an instance of char const* throw Exception2 throw Exception1对于c的异常处理机制 当一个函数发现自己无法处理某个错误时可以抛出一个异常由它的调用者捕获和处理调用者可以决定立即处理还是将问题再次抛出或者终止程序。 如果抛出的异常未被捕获则会一直向上传递直到C自动调用标准库中的terminate函数默认情况下terminate会再次调用abort函数结束程序同时生成coredump。 这就牵扯到了栈展开的概念 当一个异常抛出时程序控制权从try代码块转移到catch异常处理代码块C运行时会调用所有从try语句开始到throw语句之间构造起来的本地自动对象的析构函数销毁这些对象回收它们所占用的空间。这个过程被称为“栈展开”stackunwinding。栈展开时销毁对象的顺序与构造这些对象的顺序相反。如果在栈展开的过程中某个对象的析构函数又抛出了异常并且这个异常未被捕获C会调用terminate()函数该函数默认调用abort()函数以非正常方式结束程序。此时程序被异常结束。 上面代码中main函数中的try代码块抛出异常时在栈展开的过程中调用foo的析构函数尝试销毁foo但在foo的析构函数中再次抛出了异常并且未捕获导致C调用terminate函数进而调用abort函数异常终止程序并生成coredump。 C标准中没有禁止在析构函数中抛出异常但从设计原则上来讲析构函数应该杜绝抛出异常。析构函数中抛出异常往往是预示着这可能是一个Bad Design。如果析构函数非要抛出异常或者调用了其他可能会抛出异常的函数方法则析构函数应自己捕获这些异常。 5、构造函数抛出异常 class Foo { private:char* array; public:Foo(int flag) {array new char[1024];if (flag) {throw runtime_error(Exception thrown.);}}~Foo() {delete[] array;} };int main() {try {Foo foo(10);} catch(const exception e) {cout e.what() endl;}return 0; }打印 Exception thrown.上面代码中在Foo的构造函数中动态分配了一个字符数组随后抛出了一个异常。异常抛出时该动态数组并没有被释放Foo的析构函数也不会被调用因而发生内存泄露。 因为在类的构造函数中抛出异常系统是不会调用它的析构函数的可能会造成资源泄露所以在构造函数中抛出异常前要记得释放已经申请的资源。 class Foo { private:char* array; public:Foo(int flag) {array new char[1024];if (flag) {delete[] array;throw runtime_error(Exception thrown.);}}~Foo() {delete[] array;} };int main() {try {Foo foo(10);} catch(const exception e) {cout e.what() endl;}return 0; }不光在类的构造函数中在其他地方如一个函数中也可能出现类似的情况。在抛出异常前必须先释放前面已申请的资源否则会引起资源泄露。这个资源包括已申请的内存、打开的文件描述符、打开的网络套接字等。 6、基类析构函数非虚导致内存泄漏 定义基类Base和子类Child声明了一个基类指针base指向一个Child子类对象这样能方便地利用面向对象编程的多态性。最后通过该基类指针base删除Child对象。 C标准规定当一个派生类对象通过使用一个基类指针删除如果这个基类的析构函数是非虚的则删除结果是未知的。现实中大多情况是子类的析构函数不会被调用因此对象的派生部分不会被销毁引起内存泄露。 将基类的析构函数定义为虚函数。这样通过删除基类指针释放派生类对象时派生类的析构函数就会被调用释放全部内存。 7、删除void*指针引发内存泄露 如果我们delete对象的时候传入的是void*指针 void GeneralDelete(void* ptr){  delete ptr;}删除void* 类型的对象会导致了内存泄露。 当使用 delete 操作符进行释放对象时delete 需要根据类型信息正确地释放指针所指向的内存块。 delete的工作可以概括成 首先调用对象的析构函数然后释放该对象指针。 在调用对象的析构函数前首先需要知道该对象的类型。如果不知道该对象的类型则无法知道该调用谁的析构函数。 由于对象为void*空类型delete不会调用任何析构函数所以构造函数中动态分配的内存并没有被释放导致内存泄露。 8、成员函数尾部缺失const 一个类的const对象只能使用该类的const方法建议将所有不会修改对象数据成员的成员函数都声明为const类型。 9、使用memset初始化class C中虚函数赖以生存的底层机制vptr vtable 编译器为每个包含虚函数的类生成了一个虚函数表表中放着静态函数指针。在这个类或者其基类中定义的每一个虚函数都有一个相应的函数指针每个包含虚函数的类的对象都包含一个不可见的数据成员vptr虚函数指针该指针由构造函数自动初始化指向类的vtable当调用虚函数时代码通过vptr索引到vtbl中然后在指定位置找到函数指针 下面看一段代码 class Base { protected:char* m_pcName; public:virtual void Draw() {}char* Name(char* name) {m_pcName name;cout name endl;return m_pcName;} };class child : public Base { public:void Draw() {cout draw endl;} };int main() {Base *obj new child;memset((void*)obj, 0, sizeof(child));char* name 1;obj-Name(name);obj-Draw();return 0; }Base *obj new child;时虚函数指针已经自动初始化了再执行memset会将初始化好的指针清0因此导致程序调用虚函数draw时出现段错误。 建议 在C中对结构或变量进行初始化也可以memset。但不建议使用 memset 对一个类的对象进行初始化在某些情况下会导致程序crash。 10、对象向下转换失败 父类的对象是不可以向下转换成子类对象的只有父类指针指向某个子类对象才能进行dynamic_cast转换。不同对象之间的赋值只允许从下往上赋值传递被继承的信息。 这涉及到一个准则 1、可将派生类对象截断只使用继承来的信息 2、但不能将基类对象加长无中生有变出派生类对象 class Father{ public:int data;virtual ~Father() {}Father() {data 0;}virtual int get() {cout Father.data: data endl;return data;}void put(int val) {data val;} };class Child : public Father { public:Child() {data 5;}int get(){cout Child.data: data endl;return data;}void putchild(int value){data value;} };int main() {Father* fa new Father();auto ch dynamic_castChild*(fa);if (ch nullptr) {cout null endl;} else {cout ch-get() endl;}return 0; }打印结果 null 在上段代码的 main 函数中利用 dynamic_cast 操作符把一个父类的指针强制转换成子类指针然后调用子类的函数。在父类指针向子类指针转换时由于父类的内存空间小于子类的因此父类向子类转换失败。 具体可以参考 【Cgrammar】动态类型转换、typeid与RTTI 1type-id和exdivssion必须保持类型一致。即如果type-id是类指针类型那么exdivssion也必须是一个指针如果type-id是一个引用那么exdivssion也必须是一个引用。2父类中必须有虚函数。因为dynamic_cast在转换时会进行类型检查此时需要运行时类型信息这些信息存储在类的虚函数表中而且只有定义了虚函数的类才有虚函数表因此要求父类中必须有虚函数。 3dynamic_cast 转换指针失败会返回 NULL如果是引用转换失败则抛出bad_cast异常。因此在dynamic_cast后要判断转换是否成功如果成功才进行类函数调用否则会出现段错误。
http://www.pierceye.com/news/908715/

相关文章:

  • 校园兼职网站开发用例图最厉害的搜索引擎
  • 企业网站seo哪里好10黄页网站建设
  • 中国空间站网站色彩的应用
  • 网站分为哪些部分组成部分wordpress 用户密码加密方式
  • 产品展示栏目在网站中的作用电子商务网站建设实训方案
  • 做外贸网站需要请外贸文员吗pc端设计网站
  • 免费按模板制作微网站厦门十大软件公司
  • 免费网站模板在哪下载什么网站做的最好
  • 在智联招聘网站做销售医疗软件网站建设公司排名
  • 小程序商城设计太原搜索引擎优化
  • 旅游商业网站策划书网页在线设计平台
  • 网站建设的软文怎么写深圳我的网站
  • 动漫网站建设意义js 取网站域名
  • 网站建设项目功能需求分析报告做健身类小程序的网站
  • 专业建设网站公司哪家好建设工程合同管理多少分及格
  • 网站制作是那个大连开发区一中
  • 做预约的网站2345网址导航官网下载
  • 网站建设创建wordpress用户评论图片
  • .耐思尼克官方网站工程公司会计账务处理
  • 如何进入微网站毕业设计网站开发
  • 已经备案的网站新增ip怎么做网站分站如何做
  • 网站建设 常州怎么做网络推广营销
  • 海南建设工程信息网站常用网站建设软件
  • 福州网络推广建站网站建设工作室深圳
  • html的网站案例长春头条新闻今天
  • 免费的十大免费货源网站产品设计开发流程图
  • 做网站的内容网站建设工作室有几个部门
  • jquery win8风格企业网站模板wordpress编辑器 模板
  • 北京国互网网站建设电话免费网站怎么盈利模式
  • 网站建设图片如何加载ssh做电商 网站