C++-tips-n-traps4.pdf, Slides of Construction

Tips for C Programmers cont'd. Use inline functions and parameterized types instead of preprocessor macros, e.g.,. C. Macros de ne MAX A,B A = B ? A : ...

Typology: Slides

2022/2023

Uploaded on 02/28/2023

sumaira
sumaira 🇺🇸

4.8

(60)

263 documents

1 / 8

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
The C++ Programming
Language
C++ Tips and Traps
Outline
Tips for C Programmers
C++ Traps and Pitfalls
Eciency and Performance
1
Tips for C Programmers
Use
const
instead of #
dene
to declare
program constants,
e.g.
,
{
C
#
dene
PI 3.14159
#
dene
MAX INT 0x7FFFFFFF
#
dene
MAX UNSIGNED 0xFFFFFFFF
{
C++
const
double PI
=
3.14159;
const int
MAX INT
=
0x7FFFFFFF;
const unsigned
MAX UNSIGNED
=
0xFFFFFFFF;
Names declared with #
dene
are untyped
and unrestricted in scope
{
In contrast, names declared with
const
are
typed and follow C++ scope rules
e.g.
,
const
s have static linkage
:::
2
Tips for C Programmers (cont'd)
Use inline functions and parameterized types
instead of preprocessor macros,
e.g.
,
{
C
Macros
#
dene
MAX(A,B) (((A)
>=
(B)) ? (A) : (B))
/*
:::
*/
MAX (a
++
, b
++
); /* Trouble! */
Using a type as a parameter:
#
dene
DECLARE MAX(TYPE)
\
TYPE MAX (TYPE a, TYPE b)
\
f
return
a
>=
b ? a : b;
g
DECLARE MAX (
int
)
DECLARE MAX (
double
)
DECLARE MAX (
char
)
{
C++
inline int
MAX (
int
a,
int
b)
f
return
a
>=
b ? a : b;
g
/*
:::
*/
MAX (a
++
, b
++
); /* No problem! */
template
<
class
T
>
inline
MAX (T a, T b)
f
return
a
>=
b ? a : b;
g
3
Tips for C Programmers (cont'd)
Note, there are still some uses for prepro-
cessor, however,
e.g.
,
{
Wrapping headers and commenting out code
blocks:
#
ifndef
FOOBAR H
#
dene
FOOBAR H
:::
#
endif
{
Stringizing and token pasting
#
dene
name2(A,B) A##B
{
File inclusion
#
include
<
iostream.h
>
4
pf3
pf4
pf5
pf8

Partial preview of the text

Download C++-tips-n-traps4.pdf and more Slides Construction in PDF only on Docsity!

The C++ Programming

Language

C++ Tips and Traps

Outline

Tips for C Programmers

C++ Traps and Pitfalls

Eciency and Performance

1

Tips for C Programmers

 Use const instead of #de ne to declare

program constants, e.g.,

{ C

#de ne PI 3. #de ne MAX INT 0x7FFFFFFF #de ne MAX UNSIGNED 0xFFFFFFFF { C++

const double PI = 3.14159; const int MAX INT = 0x7FFFFFFF; const unsigned MAX UNSIGNED = 0xFFFFFFFF;

 Names declared with #de ne are untyp ed

and unrestricted in scop e

{ In contrast, names declared with const are typ ed and follow C++ scop e rules

 e.g., consts have static linkage: : :

2

Tips for C Programmers (cont'd)

 Use inline functions and parameterized typ es

instead of prepro cessor macros, e.g.,

{ C

 Macros

#de ne MAX(A,B) (((A) >= (B))? (A) : (B)) /* : : : / MAX (a++, b++); / Trouble! */  Using a typ e as a parameter:

#de ne DECLARE MAX(TYPE)
TYPE MAX (TYPE a, TYPE b)
f return a >= b? a : b; g DECLARE MAX (int) DECLARE MAX (double) DECLARE MAX (char) { C++

inline int MAX (int a, int b) freturn a >= b? a : b;g /* : : : / MAX (a++, b++); / No problem! */ template inline MAX (T a, T b) f return a >= b? a : b; g

Tips for C Programmers (cont'd)

 Note, there are still some uses for prepro-

cessor, however, e.g.,

{ Wrapping headers and commenting out co de blo cks:

#ifndef FOOBAR H #de ne FOOBAR H : : : #endif { Stringizing and token pasting

#de ne name2(A,B) A##B { File inclusion

#include <iostream.h>

Tips for C Programmers (cont'd)

 Be careful to distinguish b etween int and

unsigned

 Unlike C, C++ distinguishes b etween int

and unsigned int, so b e careful when us-

ing overloaded functions:

#include <iostream.h> inline void f (int) f cout << "f (int) called\n"; g inline void f (unsigned) f cout << "f (unsigned) called\n"; g int main (void) f f (1); // calls f (int) f (1U); // calls f (unsigned) g

5

Tips for C Programmers (cont'd)

 Consider using references instead of p oint-

ers as function arguments, e.g.,

{ C

void screen size (unsigned *height, unsigned width); / : : : */ unsigned height, width; screen size (&height, &width); { C++

void screen size (unsigned &height, unsigned &width); // : : : unsigned height, width; screen size (height, width);

 However, it is harder to tell if arguments

are mo di ed with this approach!

6

Tips for C Programmers (cont'd)

 Declare reference or p ointer arguments that

are not mo di ed by a function as const,

e.g.,

{ C

struct Big Struct f int array[ 100000 ], int size; g;

void fo o (struct Big Struct *bs); // passed as p ointer for eciency

int strlen (char *str);

{ C++

void fo o (const Big Struct &bs);

int strlen (const char *str);

 This allows callers to use const values

as arguments and also prevents functions

from accidentally mo difying their arguments

Tips for C Programmers (cont'd)

 Use overloaded function names instead of

di erent function names to distinguish b e-

tween functions that p erform the same

op erations on di erent data typ es:

{ C

int abs (int x); double fabs (double x); long labs (long x); { C++

int abs (int x); double abs (double x); long abs (long x);

 Do not forget that C++ do es NOT p er-

mit overloading on the basis of return typ e!

Tips for C Programmers (cont'd)

 Use derived classes with virtual functions

rather than using switch statements on

typ e memb ers:

{ C

#include <math.h> enum Shap e Typ e f TRIANGLE, RECTANGLE, CIRCLE g;

struct Triangle f oat x1, y1, x2, y2, x3, y3; g; struct Rectange f oat x1, y1, x2, y2; g; struct Circle f oat x, y, r; g;

struct Shap e f enum Shap e Typ e shap e; union f struct Triange t; struct Rectange r; struct Circle c; g u; g;

13

 C (cont'd)

oat area (struct Shap e *s) f switch (s->shap e) f case TRIANGLE: struct Triangle *p = &s->u.t; return fabs ( (p->x1 * p->y2 p->x2 * p->y1) + (p->x2 * p->y3 p->x3 * p->y2) + (p->x3 * p->y1 p->x1 * p->y3)) / 2; case RECTANGLE: struct Rectange *p = &s->u.r; return fabs ((p->x1 p->x2) * (p->y1 p->y2)); case CIRCLE: struct Circle *p = &s->u.c; return M PI * p->r * p->r; default: fprintf (stderr, "Invalid shap e\n"); exit (1); g g

14

 C++

#include <iostream.h> #include <math.h> class Shap e f public: Shap e () fg virtual oat area (void) const = 0; g; class Triangle : public Shap e f public: Triangle ( oat x1, oat x2, oat x3, oat y1, oat y2, oat y3); virtual oat area (void) const; private: oat x1, y1, x2, y2, x3, y3; g; oat Triangle::area (void) const f return fabs ((x1 * y2 x2 * y1) + (x2 * y3 x3 * y2) + (x3 * y1 x1 * y3)) / 2; g

 C++

class Rectange : public Shap e f public: Rectangle ( oat x1, oat y1, oat x2, oat y2); virtual oat area (void) const; private: oat x1, y1, x2, y2; g; oat Rectangle::area (void) const f return fabs ((x1 x2) * (y1 y2)); g class Circle : public Shap e f public: Circle ( oat x, oat y, oat r); virtual oat area (void) const; private: oat x, y, r; g; oat Circle::area (void) const f return M PI * r * r; g

Tips for C Programmers (cont'd)

 Use static memb er variables and functions

instead of global variables and functions,

and place enum typ es in class declarations

 This approach avoid p olluting the global

name space with identi ers, making name

con icts less likely for libraries

{ C

#include <stdio.h> enum Color Typ e f RED, GREEN, BLUE g; enum Color Typ e color = RED; unsigned char even parity (void); int main (void) f color = GREEN; printf ("%.2x\n", even parity ('Z')); g

17

Tips for C Programmers (cont'd)

 static memb ers (cont'd)

{ C++

#include <iostream.h> class My Lib f public: enum Color Typ e f RED, GREEN, BLUE g; static Color Typ e color; static unsigned char even parity (char c); g; My Lib::Color Typ e My Lib::color = My Lib::RED; int main (void) f My Lib::color = My Lib::GREEN; cout << hex (int (My Lib::even parity ('Z'))) << "\n"; g

 Note that the new C++ \namespaces"

feature will help solve this problem even

more elegantly

18

Tips for C Programmers (cont'd)

 Use anonymous unions to eliminate un-

necessary identi ers

{ C

unsigned hash (double val) f static union f unsigned asint[ 2 ]; double asdouble; g u; u.asdouble = val; return u.asint[ 0 ] ^ u.asint[ 1 ]; g { C++

unsigned hash (double val) f static union f unsigned asint[ 2 ]; double asdouble; g; asdouble = val; return asint[ 0 ] ^ asint[ 1 ]; g

C++ Traps and Pitfalls

 Ways to circumvent C++'s protection scheme:

#de ne private public #de ne const #de ne class struct

 Note, in the absence of exception handling

it is very dicult to deal with constructor

failures

{ e.g., in op erator overloaded expressions that create temp oraries

C++ Traps and Pitfalls (cont'd)

 Although a function with no arguments

must b e called with empty parens a con-

structor with no arguments must b e called

with no parens!

class Fo o f public: Fo o (void); int bar (void); g; int main (void) f Fo o f; Fo o (); // declares a function returning Fo o! f.bar (); // call metho d f.bar; // a no-op .bar (); // error! g

24

C++ Traps and Pitfalls (cont'd)

 Default Parameters and Virtual Functions

extern "C" int printf (const char *, : : : );

class Base f public: virtual void f (char *name = "Base") f printf ("base = %s\n", name); g g;

class Derived : public Base f public: virtual void f (char *name = "Derived") f printf ("derived = %s\n", name); g g;

int main (void) f Derived dp = new Derived; dp->f (); / prints "derived = Derived" */

Base bp = dp; bp->f (); / prints "derived = Base" */ return 0; g 25

C++ Traps and Pitfalls (cont'd)

 Beware of subtle whitespace issues: : :

int b = a //* divided by 4 /4; -a; / C++ prepro cessing and parsing / int b = a -a; / C prepro cessing and parsing */ int b = a/4; -a;

 Note, in general it is b est to use whites-

pace around op erators and other syntactic

elements, e.g.,

char x; int fo o (char * = x); // OK int bar (char=x); // Error

Eciency and Performance

 Inline Functions

{ Use of inlines in small programs can help p er- formance, extensive use of inlines in large projects can actually hurt p erformance by enlarging co de, bringing on paging problems, and forcing many recompilations

{ Sometimes it's go o d practice to turn-o inlin- ing to set a worst case p erformance base for your application, then go back an inline as part of p erformance tuning

 Parameter Passing

{ Passing C++ objects by reference instead of value is a go o d practice

 It's rarely to your advantage to replicate data and re o constructors and destructors un- necessarily

Eciency and Performance

(cont'd)

 Miscellaneous Tips

{ Use go o d memory (heap) management strate- gies

{ Develop go o d utility classes (for strings, in par- ticular)

{ Go o d object and proto col design (particularly, really isolating large-grained objects)

{ Give attention to paging and other ways your application uses system resources

 While C++ features, if used unwisely, can

slow an application down, C++ is not in-

herently slower than say C, particularly for

large scale projects

{ In fact, as the size and complexity of software increases, such comparisons aren't evenrele- vant since C fails to b e a practical approach whereas C++ comes into its own