[note] Effective C++ Note 5

Effective C++ Learning Note 5
(undergradute edition)

Implementations, and more on Inheritance

===========================================

postpone Definitions of vars

main purpose: avoid if:

  • in a function : return too early
  • throw an error

to sum up, to prevent a var unused.

another case: for an assigning loop

  • A: 1 ctor, 1 dtor, n assignments
  • B: n ctors, n dtors

normally, B plan is more likely to carry out the rule of encapsulation
so, use B unless:

  • you know exactly assignment is less expensive than a constructor-destructor pair.
  • you’re dealing with a performance-sensitive part of your code.

avoid returning “handles” to internals

encapsulation

class Rectangle
{
public:
    Point &upperleft() const { return pData->ulhc;}
    Point &lowerRight() const { return pData->lrhc;}
    ...
}

the const function is defined to remain the member unchanged. however, by returning a reference, we can astonishingly find we could change its private members!!!

dangling handles

when returning a reference or pointer, sometimes it may be just towards a expired “shell” then.

inlining

  • if we define a member function in one class, it’ll be implicitly conversed to inline function

public inheritance: is-a relationship

in the “All birds can fly, penguins are birds, penguins can’t fly, uh oh” problem, we have two main solutions:

  1. not to define void fly() in class bird
  2. when penguin obj calls the fly(), throw an exception

however, our program is advised to stop by the entrance it starts, that’s to say, alarms when compiling and suspends then.

if we don’t need to deal with problems like flying, now and in the future, we may not distiguish the flying-birds and those cannot, but in order to more vividly reflect the reality, we may need to distinguish then.

scope problems: avoid hide name

Our goal … however, is to know enough to avoid unpleasant surprises, and for that task, we already have plenty of information.

  • how names are found: from the local scope, to containing scope, then to namespace scope, finally global.
  • don’t hide existing name: don’t declare a var or function that is of the same name to an existing one (especially the non-virtual ones).
  • when hiding is unavoidable: attach using Base::mf1(); in the derived class
  • in public inheritance, hiding parts of functions or vars is somewhat incorrect (for the is-a relation).
  • in private inhe, when we need to just inherit partially, try forwarding function like this:
    class Base{
    public:
        virtual void mf1() = 0;
        virtual void mf1(int);
    };
    class Derived : private Base{
    public:
        virtual void mf1() { Base::mf1();}
    }
    Derived d;
    int x;
    d.mf1(); // right
    d.mf1(x); // wrong
    

distinguish the inheritance of interface and impl.

typeinterfaceimplementation
non-virtualyesyes
impure virtualyesyes(polymorphic)
pure virtualyesno
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值