[note] Effective C++ Chapter 4

Effective C++ Learning Note 4
(undergradute edition)

Designs and Declarations

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

we now only treat the possible meaningful advice which can work for classes

easy and clear Interface with high-tolerance of client errors

type system

Many client errors can be prevented by the introduction of new types.

e.g. in the Date class, we can encapsule the y,m,d in different classes

struct Day 
{
   explict Day(int d): val(d){ };
   int val;
};
//and then we can confine the client's attempt to limited range like this:
Date d(Month(3), Day(30), Year(1995));

aside from that, to guarantee the type safety while month is define in [1, 12], we could use functions like static Month Jan() (this avoid the problematic non-local static initialization.)

my thinking about the static function to replace a non-local static obj: when we init the whole class’s obj, its static objs may haven’t been created yet. it’s a compatible process.

restrict the behavior of clients

  • Add const. in item 3, we talked about the if(a*b=c) problem,
  • Avoiding gratuitous incompatibilities with the built-in types: such as using size() for all DT in STL.
  • Automatically delete (or sth like this) for client

Treat classes as types

Designing good classes is challenging because designing good types is challenging.

  • created and destroyed: ctors, dtors, new, delete
  • initialization differ from object assignment
  • passed by value: copy constructor defines how pass-by-value is implemented for a type.
  • restrictions on legal values(in the former item we have just talked about)
  • fit into an inheritance graph
  • type conversions: even a specific conver-function
  • the compatibility with existing functions and objs; standard functions should be disallowed? (copy disallow)
  • interfaces design
  • meaningful?: general and necessary.

prefer const&

aside from built-in types, iterators, functionals, this is a very important and useful rules.

why?

to avoid repeated invacation of ctors and dtors. while remain the master copy unchanged.

effectively solve the problem of base-slicing

which happened when we pass a derived obj to a base ptr

扫描二维码关注公众号,回复: 11168593 查看本文章

obj of small types sometimes contains not much more than a pointer(which is the impl. of reference), but if we pass by reference, we’d call ctors of all of the units it points to.

issues of “unnecessary”

small user-class may not perform well dealing with pass-by-val (this is essentially connected to the reason why we pass by reference, not just superficially for being small)

the small class will be enlarged

No reference when return an obj

here don’t be entangled with the efficiency problem,

when deciding between returning a reference and returning an object, your job is to make the choice that offers correct behavior.

some bad code ex:

//friend function: in stack(deleted then)
const Rational& operator*(const Rational& lhs, const Rational& rhs)
{
    Rational result(lhs.n*rhs.n, lhs.d*rhs.d);
    return result;
}

//allocate in heap by 'new': leakage
const Rational& operator*(const Rational &lhs, const Rational &rhs)
{
    Rational *result = new Rational(lhs.n*rhs.n, lhs.d*rhs.d);
    return *result;
}

//static obj with global life: there is only ONE obj
const Rational &operator*(const Rational &lhs, const Rational &rhs)
{
    static Rational result;
    result = ...;
    return result;
}
//in the last case, we may think of putting static into vector...there'll still be the cost of dtors and ctors, also global life means some memory unnecessrily occupied, underlying waste in the long run.

// a possible version
inline const Rational operator*(const Rational &lhs, consr Rational &rhs)
{
    return Rational(...);
}
it act like the 'static array', while delete unnecessary ones in time

Declare data members private

  • syntactic consistency: clients just need to call by name()s
  • fine-grained access control: readOnly, writeOnly and readWrite.
  • encapsulation

encapsulation

private is the highest control: if we declare a var protected or public, then we eliminate or change it back to private, it’ll be disastrous (piles of codes to rewrite, retest, redocument or recompile)
it affords us the flexibility to change things in a way that affects only a limited number of clients.

thus, we can say that protected is no more encapsulated than public.

Prefer non-member non-friend functions to member functions

the non-member non-friend function yields greater encapsulation in the class than a member or friend function.
it can only integrate functions which have been defined, thus with higher restriction.

tips:

  • First, this reasoning applies only to non-member non-friend functions.
  • The second thing to note is that just because concerns about encapsulation dictate that a function be a non-member of one class doesn’t mean it can’t be a member of another class(such as a utility class). what we want is high encapsulation

functions stated above should be declared in one namespace(where functions it calls are declared)

Declare non-member functions when type conversions should apply to all parameters

sometimes we need implicit conversions. such as a rational-computing class

class Rational {
public:
...
const Rational operator*(const Rational& rhs) const;
};

Rational a(1, 8);
Rational ans1 = a * 2 // right
Rational ans2 = 2 * a // wrong

from the bug above, int won’t automatically converse to Rational
to solve that, we’d created a function that has two param(where the two obj could be conversed to Rational objs)

from this example, we could see that, if member functions cannot solve the problem, friend function may not be necessary.

(about friend function)Whenever you can avoid friend functions, you should, because, much as in real life, friends are often more trouble than they’re worth.

effective std::swap()

related to templates. thus, we don’t talked about it too much

we just talked about the pimpl idiom:
to declare a pimpl(pointer to implementation), and if the class is too large, we just need to swap the pointer.

原创文章 42 获赞 17 访问量 1517

猜你喜欢

转载自blog.csdn.net/weixin_45502929/article/details/105590038