Happy Mittal
Happy Mittal

Reputation: 3747

copy constructor for const object

I have a following class foo

class foo
{
    int *arr; // arr holds numbers
    int sz; // size of array
    public:
    // Suppose I have made default and 1 parameter c'tor
    foo(const foo &f)
    {
        sz = f.sz;
        arr = new int[sz];
        for(int i=0;i<sz;i++)
            arr[i]=f.arr[i];
    }
};

int main()
{
    foo x(5); //5 is size of array
    const foo y = x; //doesn't work as I haven't initialized in member-initialization list, but how to write for loop in member initialization list ?
}  

So How do I write for loop in member initialization list ?

Upvotes: 0

Views: 1414

Answers (3)

Michael Burr
Michael Burr

Reputation: 340218

You should clarify your problem, because the one in the question doesn't actually exist.

The const foo y = x; line will compile and work with that copy constructor. A const object under construction isn't "const' until the constructor has completed. So the constructor body is permitted to modify the object even if the object being constructed is const.

Also note that the loop in the example isn't even modifying anything that's ever const - since the array is allocated dynamically, those array elements are modifiable even if the object itself isn't. For example, the arr pointer isn't modifiable after the ctor has completed, but arr[0] still is.

Try out the following to see both points in action:

#include <stdio.h>
#include <algorithm>

class foo
{
    int *arr; // arr holds numbers
    int sz; // size of array
    public:
    foo() : arr(0), sz(0) { puts("default ctor");}
    foo(int x) : arr(0), sz(x) {
        puts( "int ctor");
        arr = new int[sz];
        for(int i=0;i<sz;i++)
            arr[i]=0;
    }

    foo(const foo &f)
    {
        puts("copy ctor");
        sz = f.sz;
        arr = new int[sz];
        for(int i=0;i<sz;i++)
            arr[i]=f.arr[i];
    }

    ~foo() {
        delete [] arr;
    }

    foo& operator=(const foo& rhs) {
        if (this != &rhs) {
            foo tmp(rhs);
            std::swap( arr, tmp.arr);
            std::swap( sz, tmp.sz);
        }

        return *this;        
    }

    void update() const {
        for(int i = 0; i < sz; i++) {
            arr[i] = arr[i] + 1;
        }
    }

    void dump() const {
        for(int i = 0; i < sz; i++) {
            printf("%d ", arr[i]);
        }
        puts("");
    }
};

int main()
{
    foo x(5); //5 is size of array
    const foo y = x; 

    y.dump();
    y.update(); // can still modify the int array, even though `y` is const
    y.dump();
}  

I think you may be confusing constructing const objects with constructing objects that have const members since those members must be initialized in the initialization list.

Upvotes: 2

justin
justin

Reputation: 104698

You could just use a std::vector in this case… anyways.

Typically, I will create a private static method which will perform the allocation and copy. Then the initialization list may be used:

static int* CloneInts(const foo& f) {
    int* ints = new ...
    ...copy them from @a f.arr...
    return ints;
}

Then your init-list would look like:

foo(const foo& f) : arr(CloneInts(f)), sz(f.sz) {

Upvotes: 3

jvstech
jvstech

Reputation: 864

Have you tried constructing it with the copy constructor directly?

const foo y(x);

Upvotes: 3

Related Questions