Você está na página 1de 15

Constructors

• It is a member function which initializes a class.

• A constructor has:

(i) the same name as the class itself

(ii) no return type

• A constructor is called automatically whenever a new instance of a class is


created.

• You must supply the arguments to the constructor when a new instance is
created.

• If you do not specify a constructor, the compiler generates a default


constructor for you (expects no parameters and has an empty body).

Example

class rectangle {

private:

float height;

float width;

int xpos;

int ypos;

public:

rectangle(float, float); // constructor

void draw(); // draw member function

void posn(int, int); // position member function

void move(int, int); // move member function

};

rectangle::rectangle(float h, float w) {

height = h;

width = w;

xpos = 0;

ypos = 0;
}

Example

void main() {

rectangle rc(3.0, 2.0);

rc.posn(100, 100);

rc.draw();

rc.move(50, 50);

rc.draw();

Warning: attempting to initialize a data member of a class explicitly in the class


definition is a syntax error.

Overloading constructors

• You can have more than one constructor in a class, as long as each has a
different list of arguments.

• Example

class rectangle {

private:

float height;

float width;

int xpos;

int ypos;

public:

rectangle(float, float); // constructor

rectangle(); // another constructor

void draw(); // draw member function

void posn(int, int); // position member function

void move(int, int); // move member function

};

rectangle::rectangle() {
height = 10;

width = 10;

xpos = 0;

ypos = 0;

void main() {

rectangle rc1(3.0, 2.0);

rectangle rc2();

rc1.draw();

rc2.draw();

objects as members of classes

• A class may have objects of other classes as members.

• Example

class properties {

private:

int color;

int line;

public:

properties(int, int); // constructor

};

properties::properties(int c, int l) {

color = c;

line = l;

class rectangle {

private:

float height;
float width;

int xpos;

int ypos;

properties pr; // another object

public:

rectangle(float, float, int, int ); // constructor

void draw(); // draw member function

void posn(int, int); // position member function

void move(int, int); // move member function

};

rectangle::rectangle(float h, float w, int c, int l):pr(c, l) {

height = h;

width = w;

xpos = 0;

ypos = 0;

};

void main() {

rectangle rc(3.0, 2.0, 1, 3);

What is a destructor?

• It is a member function which deletes an object.

• A destructor function is called automatically when the object goes out of


scope:

(1) the function ends

(2) the program ends

(3) a block containing temporary variables ends

(4) a delete operator is called

A destructor has:

(i) the same name as the class but is preceded by a tilde (~)
(ii) no arguments and return no values

Example

class string {

private:

char *s;

int size;

public:

string(char *); // constructor

~string(); // destructor

};

string::string(char *c) {

size = strlen(c);

s = new char[size+1];

strcpy(s,c);

string::~string() {

delete []s;

Destructors

• If you do not specify a destructor, the compiler generates a default


destructor for you.

• When a class contains a pointer to memory you allocate, it is your


responsibility to release the memory before the class instance is
destroyed.

What is a copy constructor?

• It is a member function which initializes an object using another object of


the same class.

• A copy constructor has the following general function prototype:

class_name (const class_name&);

Example
class rectangle {

private:

float height;

float width;

int xpos;

int ypos;

public:

rectangle(float, float); // constructor

rectangle(const rectangle&); // copy constructor

void draw(); // draw member function

void posn(int, int); // position member function

void move(int, int); // move member function

};

rectangle::rectangle(const rectangle& old_rc) {

height = old_rc.height;

width = old_rc.width;

xpos = old_rc.xpos;

ypos = old_rc.ypos;

void main() {

rectangle rc1(3.0, 2.0); // use constructor

rectangle rc2(rc1); // use copy constructor

rectangle rc3 = rc1; // alternative syntax for

// copy constructor

}
Defining copy constructors is very important

• In the absence of a copy constructor, the C++ compiler builds a default


copy constructor for each class which is doing a memberwise copy
between objects.

• Default copy constructors work fine unless the class contains pointer data
members ... why???

• Example

#include <iostream.h>

#include <string.h>

class string {

private:

char *s;

int size;

public:

string(char *); // constructor

~string(); // destructor

void print();

void copy(char *);

};

void string::print() {

cout << s << endl;

void string::copy(char *c) {

strcpy(s, c);

void main() {

string str1("George");

string str2 = str1; // default copy constructor


str1.print(); // what is printed ?

str2.print();

str2.copy("Mary");

str1.print(); // what is printed now ?

str2.print();

Operator Overloading

 Operator overloading used for customised behaviour of different


operators

 Declared using operator@ keyword, where @ represents the


operator that’s being overloaded

Example: Operator Overloading

class OverloadingExample {

private:

int m_LocalInt;

public:

OverloadingExample(int j) // default constructor {

m_LocalInt = j;

int operator+ (int j) // overloaded + operator {

return (m_LocalInt + j);

};

void main() {

OverloadingExample object1(10);

cout << object1 + 10; // overloaded operator called

}
Types of Operator

 Unary operator

 Binary operator

Unary Operators

 Operators attached to a single operand (-a, +a, --a, a--, ++a, a++)

Example: Unary Operators

class UnaryExample {

private:

int m_LocalInt;

public:

UnaryExample(int j) {

m_LocalInt = j;

int operator++ () {

return (m_LocalInt++);

};

void main() {

UnaryExample object1(10);

cout << object1++; // overloaded operator results in value


// 11

Non-Overloadable Operators

 Operators that cannot be overloaded due to safety reasons:

 Member Selection ‘.’ operator

 Member dereference ‘.*’ operator

 Exponential ‘**’ operator


 User-defined operators

 Operator precedence rules

Operator Overloading and Inheritance

 An operator is overloaded in super class but not overloaded in derived


class is called non-member operator in derived class

 In above, if operator is also overloaded in derived class it is called


member-operator

 = ( ) [ ] –> –>* operators must be member operators

 Other operators can be non-member operators

Automatic Type Conversion

 Automatic type conversion by the C++ compiler from the type that
doesn’t fit, to the type it wants

 Two types of conversion:

 Constructor conversion

 Operator conversion

Example: Constructor Conversion

class One {

public:

One() {}

};

class Two {

public:

Two(const One&) {}

};

void f(Two) {}

void main() {

One one;

f(one); // Wants a Two, has a One

}
Automatic Type Conversion

 Automatic type conversion by the C++ compiler from the type that
doesn’t fit, to the type it wants

 Two types of conversion:

 Constructor conversion

 Operator conversion

Constructor Conversion

 Constructor having a single argument of another type, results in automatic


type conversion by the compiler

 Prevention of constructor type conversion by use of explicit keyword

Example: Constructor Conversion

class One {

public:

One() {}

};

class Two {

public:

Two(const One&) {}

};

void f(Two) {}

void main() {

One one;

f(one); // Wants a Two, has a One

Operator Conversion

 Create a member function that takes the current type

 Converts it to the desired type using the operator keyword followed by


the type you want to convert to
 Return type is the name of the operator overloaded

 Reflexivity - global overloading instead of member overloading; for code


saving

Example: Operator Conversion

class Three {

int m_Data;

public:

Three(int ii = 0, int = 0) : m_Data(ii) {}

};

class Four {

int m_Data;

public:

Four(int x) : m_Data(x) {}

operator Three() const {

return Three(m_Data);

};

void g(Three) {}

void main()

Four four(1);

g(four);

g(1); // Calls Three(1,0)

Type Conversion Pitfalls

 Compiler performs automatic type conversion independently, therefore it


may have the following pitfalls:

 Ambiguity with two classes of same type

 Automatic conversion to more than one type - fan-out


 Adds hidden activities (copy-constructor etc)

Explicit initialization with constructors

A class object with a constructor must be explicitly initialized or have a default


constructor.

Explicit initialization using a constructor is the only way to initialize nonstatic


constant and reference class members.

A class object that has no constructors, no virtual functions, no private or


protected members, and no base classes is called an aggregate.

Examples of aggregates are C-style structures and unions.

You explicitly initialize a class object when you create that object.

There are two ways to initialize a class object.

Using a parenthesized expression list.

The compiler calls the constructor of the class using this list as the constructor's
argument list.

Using a single initialization value and the = operator.

Because this type of expression is an initialization, not an assignment, the


assignment operator function, if one exists, is not called.

The type of the single argument must match the type of the first argument to the
constructor.

If the constructor has remaining arguments, these arguments must have default
values.

The following example shows the declaration and use of several constructors
that explicitly initialize class objects:

// This example illustrates explicit initialization

// by constructor.

#include <iostream>

using namespace std;

class complx {

double re, im;

public:

// default constructor
complx() : re(0), im(0) { }

// copy constructor

complx(const complx& c) { re = c.re; im = c.im; }

// constructor with default trailing argument

complx( double r, double i = 0.0) { re = r; im = i; }

void display() {

cout << "re = "<< re << " im = " << im << endl;

};

int main() {

// initialize with complx(double, double)

complx one(1);

// initialize with a copy of one

// using complx::complx(const complx&)

complx two = one;

// construct complx(3,4)

// directly into three

complx three = complx(3,4);

// initialize with default constructor

complx four;

// complx(double, double) and construct

// directly into five

complx five = 5;

one.display();

two.display();

three.display();

four.display();
five.display();

The above example produces the following output:

re = 1 im = 0

re = 1 im = 0

re = 3 im = 4

re = 0 im = 0

re = 5 im = 0

Você também pode gostar