首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++核心准则​讨论:将函数设为公共和虚拟,或保护和非虚拟

对于Base,调用代码可能会尝试通过指向Base指针销毁派生对象,例如在使用unique_ptr 。...这种情况导致较早编码标准对所有函数都必须是虚拟提出了全面的要求。这太过分了(即使是常见情况);相反,规则应该是且仅函数是公共,才将它们虚函数化。...可以看作只是另一种操作,尽管具有使非虚调用变得危险或错误特殊语义。因此,对于函数,选择是根据是否允许通过指向Base指针实际上调用它。“非虚”不是一种选择。...B是可以自己实例化和具体,因此函数必须是公共,才能创建和销毁B对象。...更好设计是遵循该产品建议,为其提供保护非虚函数

1.1K20

C++核心准则C.35:函数要么是公开函数,要么是保护非虚函数

C.35: A base class destructor should be either public and virtual, or protected and nonvirtual 函数要么是公开函数...为了避免无定义行为。如果函数是公有的,那么调用侧代码就会尝试使用指针销毁派生对象,在函数为非虚函数其结果没有定义。...如果函数保护,那么调用侧代码就无法通过类型指针销毁派生对象,这是函数就没有必要一定是虚函数函数保护而不是私有的,这样派生函数才能调用它。...通常,设计者不会知道在函数中应该执行什么样动作。...我们可以想象一种需要保护函数函数情况:希望允许派生对象(只有这个类型)通过指针销毁另外一个对象(不是它自己)。但是我们还没有在实际开发中遇到这种情况。

1K20
您找到你想要的搜索结果了吗?
是的
没有找到

《C++Primer》第十五章 面向对象程序设计

派生成员或者友元只能通过派生对象来访问保护成员,派生对于一个对象中保护成员没有任何访问特权 理解最后一条规则可以参考如下例子: class Base { protected:...派生转换可访问性 假定D继承B: 只有当D公有地继承B,用户代码才能使用派生转换;如果D继承B方式是保护或者私有的,则用户代码不能使用该转换 无论D以什么方式继承B,D成员函数和友元都能使用派生转换...友元在访问派生成员具有特殊性,同样派生友元也不能随便访问成员。 5....只要函数是虚函数,就能确保当我们delete指针将运行正确函数版本。 我们之前介绍过一条经验准则:如果一个需要函数,那么它同样也需要拷贝和赋值操作。...执行构造函数,该对象派生部分是未被初始化状态;执行函数,派生部分已经被销毁了。

1.2K20

C++核心准则C.127:包含虚函数应该有虚函数保护函数

C.127: A class with a virtual function should have a virtual or protected destructor C.127:包含虚函数应该有虚函数保护函数‍...包含虚函数通常(大多数情况下)通过指向指针使用。通常,最后一个使用者必须通过指向指针调用delete操作,通常是指向智能指针,因此函数应该是公开函数。...稍微特殊一些情况是:如果不希望支持通过指向指针销毁对象,函数应该是保护非虚函数。参见C.35。...包含虚函数函数要么是公开函数,要么是保护非虚函数。...提示针对包含虚函数却没有虚函数销毁操作。

74720

C++基础知识

使用智能指针可以很大程度上避免这个问题,因为智能指针就是一个超出了作用域是,会自动调用函数函数会自动释放资源。...pa,pb 之间互相引用,两个资源引用计数为 2,要跳出函数,智能指针 pa,pb 两个资源引用计数会减一,但是两者引用计数还是为 1,导致跳出函数资源没有被释放(A B 函数没有被调用...函数 函数与构造函数对应,对象结束其生命周期,如对象所在函数已调用完毕,系统会自动执行函数。...顺序 派生本身函数 对象成员函数 函数 因为函数没有参数,所以包含成员对象函数形式上并无特殊之处。...函数与虚函数 函数必须是虚函数,因为将可能会被继承函数设置为虚函数,可以保证当我们 new 一个子类,然后使用指针指向该子类对象,释放指针可以释放掉子类空间,防止内存泄漏

1.4K32

两万字总结《C++ Primer》要点

合成函数一个未定义自己函数,编译器会为它定义一个合成函数函数体本身并不直接销毁成员。...派生构造函数: 每个控制自己成员初始化过程。派生首先初始化部分,然后按照声明顺序依次初始化派生成员。 派生使用成员: 派生可以访问公有成员和保护成员。...不能创建抽象对象。 15.5 访问控制与继承 保护成员: 派生成员和友元只能访问派生对象中部分保护成员;对于普通对象中成员不具有特殊访问权限。...P543 公有、私有和保护继承: 派生访问说明符对于派生成员(及友元)能否访问其直接成员无影响; 对成员访问权限只与访问说明符有关。...::: 15.7 构造函数与拷贝控制 (1)虚函数中将函数定义成虚函数以确保执行正确函数版本。

1.5K30

两万字总结《C++ Primer》要点

合成函数一个未定义自己函数,编译器会为它定义一个合成函数函数体本身并不直接销毁成员。...派生构造函数: 每个控制自己成员初始化过程。派生首先初始化部分,然后按照声明顺序依次初始化派生成员。 派生使用成员: 派生可以访问公有成员和保护成员。...不能创建抽象对象。 15.5 访问控制与继承 保护成员: 派生成员和友元只能访问派生对象中部分保护成员;对于普通对象中成员不具有特殊访问权限。...P543 公有、私有和保护继承: 派生访问说明符对于派生成员(及友元)能否访问其直接成员无影响; 对成员访问权限只与访问说明符有关。...::: 15.7 构造函数与拷贝控制 (1)虚函数中将函数定义成虚函数以确保执行正确函数版本。

1.7K20

C++关键知识点梳理

每个虚继承子类都有一个虚指针(占用一个指针存储空间,4字节)和虚表(不占用对象存储空间)派生重新定义虚函数,则将派生函数地址添加到虚函数表中。...一个指针指向一个派生对象,虚函数表指针指向派生对象函数表。调用虚函数,由于派生对象重写了派生对应函数表项,在调用时会调用派生函数,从而产生多态。...虚函数:为了防止delete指向派生对象指针只调用函数引起内存泄漏using namespace std;class Base {public: virtual ~ Base...pb->func(); delete pb; return 0;}运行结果如下:Derived func2delete Deriveddelete BaseBase函数是普通函数...,则delete pb只会调用Base函数纯虚函数:虚函数声明时候加上=0,包含纯虚函数是抽象,不可实例化,纯虚函数必须被派生实现。

93230

智能指针在面试中得重要地位!

,由调用者复制删除 //std::unique_ptr,又会自动对其所指向对象实施delete //std::unique_ptr,又会自动对其所指向对象实施delete class...,中必须具备一个虚函数 }; //改进返回值型别 template() 重载 -> 号,智能指针指向数据类型为自定义结构体,通过 -> 运算符可以获取其内部指定成员。...operator 重载了 [] 运算符, unique_ptr 指针指向一个数组,可以直接通过 [] 获取指定下标位置处数据。...并且,B持有的指针不会影响A引用计数 因此 std::shared_ptr不再指涉到A,不会阻止A被 */ // 要点速记 // • 使用 std: :weak_ptr 来代替可能空悬 std

1K20

《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)

3、构造函数不须要是虚函数,也不同意是虚函数,由于创建一个对象我们总是要明白指定对象类型,虽然我们可能通过实验室指针或引用去訪问它但却不一定,我们往往通过指针来销毁对象。...假设中采用是非虚函数删除指针指向派生对象就不会触发动态绑定,因而只会调用函数,而不会调用派生函数。...函数没有参数,也没有返回值,而且不能重载,在一个中只能有一个函数撤销对象,编译器也会自动调用函数。...,在销毁一个对象,先调用子类函数,然后再调用函数。...假设中采用是非虚函数删除指针指向派生对象就不会触发动态绑定,因而只会调用函数,而不会调用派生函数

2.3K40

被蚂蚁面试官拷打了,基础真的是太重要了...

6、C++中为什么父要定义虚函数(可能看我不太懂C++,问了个奇怪问题) 在C++中,定义虚函数(virtual destructor)主要是为了解决多重继承带来问题。...一个子类被多次继承,如果在子类函数中没有正确地调用函数,就可能导致资源没有被正确释放,从而引起资源泄漏。...而虚函数可以确保在子类函数中正确地调用函数,从而避免资源泄漏问题。...具体来说,一个被多次继承,如果在最顶层子类函数中没有正确地调用函数,就可能导致资源没有被正确释放。...而如果定义了虚函数,则在最顶层子类函数中会自动调用函数,从而确保资源被正确释放。

16221

C++之面向对象三个基本特征

函数 函数作用是在对象撤销之前做必要“清理现场”工作;派生对象从内存中撤销,一般先调用派生函数,再调用函数。...本例中定义了两个 Base 和派生 Derived,它们都有自己构造函数函数。...从运行结果可以看出,执行delete p;语句只调用了函数,却没有调用派生函数。...执行delete p;语句,会先执行派生函数,再执行函数,这样就不存在内存泄露问题了。...通常来说,如果中存在一个指向动态分配内存成员变量,并且函数中定义了释放该动态分配内存代码,那么就应该将函数声明为虚函数

1.1K60

第 15 章 面向对象程序设计

---- 15.5 访问控制与继承 派生成员和友元只能访问派生对象中部分保护成员,对于普通对象中成员不具有特殊访问权限,即在派生中也不能通过对象来访问 protected...假定 D继承自 B: 只有当 D公有地继承 B,用户代码才能使用派生类型转换;如果 D继承 B方式是保护或私有的,则用户代码不能使用该转换。...函数虚属性会被继承,无论派生中使用合成函数还是自定义函数,都将是虚函数。这样,就能保证 delete指针总能运行正确函数版本。...如前所述,一个中存在拷贝控制成员,编译器不会为这个合成移动操作。对于需要定义虚函数,也是如此。...构造函数具有默认实参,实参不会被继承,而是派生会获得多个继承构造函数,每个构造函数分别省略掉一个含有默认实参形参。

1K30

【C++】异常+智能指针+特殊和类型转换

C++经常使用RAII来解决上面这种问题,即将资源生命周期和对象生命周期进行绑定,对象初始化时资源创建,对象资源销毁。 2....shared_ptr构造函数可以直接支持传递删除器,实际底层又套了很多来解决,因为他还要将这个删除器传递给函数,删除器肯定是在函数中使用嘛,所以还有一个中间传递过程。...private: //封为私有,不让你随便在任意内存位置创建对象,但没有说不让你创建对象 HeapOnly(){} }; 首先需要知道一点是,栈和数据段上对象在其作用域结束或程序终止,会自动调用函数完成对象资源清理工作...因为封掉函数的话,栈和数据段上就无法创建出对象了,因为这些对象无法调用函数完成资源清理,所以就只能在堆上创建出对象 了,所以封掉函数也是一种只在堆上创建对象做法。...另一种就是实现一个内部垃圾回收GC,用这个来定义出静态对象_gc,这个_gc是单例成员变量,所以程序结束,静态对象_gc生命结束,会自动调用自己函数,而GC本身就是内部类,可以直接访问到静态指针

30940

女朋友:一个 bug 查了两天,再解决不了,和你代码过去吧!

加了日志后,我们发现接受一个新连接: HttpSession 构造了一次,无; HttpConnection 构造一次,一次 断开连接: HttpSession 一次,然后崩溃。...到这里我们看出,程序行为已经不符合预期了:接受连接,HttpSession 和 HttpConnection 应该均构造一次,不会发生;连接断开,HttpSession 和 HttpConnection...应该均一次。...成员变量智能指针),HttpSession 即使不使用 HttpConnection 对象,在断开连接,HttpSession 会触发其成员变量 HttpConnection 对象,而此时... 智能指针对象,pConnection 出了 onAccept 函数作用域之后,会自动该对象,其持有的资源引用计数变为 0,导致 HttpConnection

62720

C++构造函数抛出异常注意事项

同时,由于构造函数本身也是一个函数,在函数体内抛出异常将导致当前函数运行结束,并释放已经构造成员对象,包括其成员,即执行直接和成员对象函数。考察如下程序。...由于在B构造函数中抛出了异常,而此异常并未在构造函数中被捕捉,所以导致B构造函数执行中断,对象b并未构造完成。在B构造函数“回滚”过程中,c函数A函数相继被调用。...RAII即资源获取即初始化,也就是说在构造函数中申请分配资源,在函数中释放资源。因为C++语言机制保证了,一个对象创建时候,自动调用构造函数对象超出作用域时候会自动调用函数。...因此,构造函数不得已抛出异常,可以利用“智能指针”unique_ptr来防止内存泄露。...,通过智能指针对内存资源管理,尽管在B构造函数抛出异常导致B函数未被执行,但A函数仍然在对象pA生命周期结束被调用,避免了资源泄漏。

2.1K40

c++构造函数是否可以抛出异常_什么叫抛出异常

同时,由于构造函数本身也是一个函数,在函数体内抛出异常将导致当前函数运行结束,并释放已经构造成员对象,包括其成员,即执行直接和成员对象函数。考察如下程序。...由于在B构造函数中抛出了异常,而此异常并未在构造函数中被捕捉,所以导致B构造函数执行中断,对象b并未构造完成。在B构造函数“回滚”过程中,c函数A函数相继被调用。...RAII 即资源获取即初始化,也就是说在构造函数中申请分配资源,在函数中释放资源。因为 C++ 语言机制保证了,一个对象创建时候,自动调用构造函数对象超出作用域时候会自动调用函数。...因此,构造函数不得已抛出异常,可以利用智能指针 unique_ptr 来防止内存泄露。...,通过智能指针对内存资源管理,尽管在B构造函数抛出异常导致B函数未被执行,但 A 函数仍然在对象 pA 生命周期结束被调用,避免了资源泄漏。

1.6K10

后台开发:核心技术与应用实践 -- C++

):公用成员和保护成员在派生中成了私有成员,其私有成员仍为私有 保护继承(protected inheritance):公用成员和保护成员在派生中成了保护成员,其私有成员仍为私有...在派生,派生是不能继承函数,也需要通过派生函数去调用函数。...在派生中可以根据需要定义自己函数,用来对派生中所增加成员进行清理工作;清理工作仍然由函数负责。...在执行派生函数,系统会自动调用函数和子对象函数,对和子对象进行清理。...C++明确指出,derived class 对象经由 base class 指针被删除 而该 base class 带着一个non-virtual 函数, 导致对象 derived 成分没被销毁掉

1.3K10

扫码

添加站长 进交流群

领取专属 10元无门槛券

手把手带您无忧上云

扫码加入开发者社群

相关资讯

热门标签

活动推荐

    运营活动

    活动名称
    广告关闭
    领券