-3

I have a B class and it has a class C member. B objects are stored in a vector. Full Code and output as follows:

#ifndef B_H
#define B_H

#include "C.h"

class B
{
public:
    B( int = 0 );           // constructor
    B( const B& );  // copy constructor
    ~B();           // destructor
    const B &operator=( const B & );    // assignment operator
    C c();          // return C object
    void val( int );// set val
    int val() const;// return val
private:
    C _c;           // C object
    int _val;       // a value
};

#include "B.h"
#include <iostream>

using namespace std;

B::B( int val )
{
    _val = val;

    cout << "B constructor called" << endl;
}

B::B( const B &other )
{
    _c = other._c;

    cout << "B copy constructor called" << endl;
}

B::~B()
{
    cout << "B destructor called" << endl;
}

const B &B::operator=( const B &other )
{
    if ( &other != this ) {     // avoid self-assignment

        _c = other._c;
    }

    return *this;
}

C B::c()
{
    return _c;
}

void B::val( int val )
{
    _val = val;
}

int B::val() const
{
    return _val;
}

#ifndef C_H
#define C_H

class C
{
public:
    C();            // constructor
    ~C();           // destructor
    void val( int );// set val
    int val() const;// return val
private:
    int _val;       // a value
};

#endif

#include "C.h"
#include <iostream>

using namespace std;

C::C()
{
    _val = 0;

    cout << "C constructor called" << endl;
}

C::~C()
{
    cout << "C destructor called" << endl;
}

void C::val( int val )
{
    _val = val;
}

int C::val() const
{
    return _val;
}

#include <vector>
#include <iostream>
#include "B.h"

using namespace std;

const int n = 5;

vector<B> v( n );

int main()
{
    for ( int i = 0; i < n; i++ )
        v[i] = B( i );

    for ( int i = 0; i < n; i++ )
        B &b = v[i];


    for ( int i = 0; i < n; i++ ) {

        B &b = v[i];

        b.c().val( 5 );
    }

    for ( int i = 0; i < n; i++ ) {

        B &b = v[i];

        cout << b.c().val() << endl;
    }

    cin.ignore( 1 );

    return 0;
}

output:

C destructor called
C destructor called
C destructor called
C destructor called
C destructor called
0
C destructor called
0
C destructor called
0
C destructor called
0
C destructor called
0
C destructor called

problem: at each cycle C object is destructed and b.c().val() returns with default ( zero ) value.

question: why?

output is belong to last two for.

Kun
  • 1
  • 2

2 Answers2

2

Your B::c member function returns a C by value. That is, it copies the _c object that is being held by the B object out of the function. You are calling val on that copy and do not affect the member _c.

Consider the line:

b.c().val( 5 );

b.c() returns a temporary copy of b's _c object. You then call val on that temporary. Then the temporary is destroyed at the end of the statement. It is this temporary that is being destroyed in each iteration. That temporary is outputting C destructor called.

If you want to affect the member _c, you'll need to return it by reference:

C& B::c()
{
    return _c;
}
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
0

Your problem lies here:

C c();          // return C object

In the B object. Try to understand what this is doing.

Nim
  • 33,299
  • 2
  • 62
  • 101