I have:

class ANew
{
    private:
        vector<CustomType> ArrayOfTypes;

    public:
        ANew() : ArrayOfTypes(0) {}
        ~ANew() {}

        ANew& operator ()(int I)
        {
            return ArrayOfTypes[I];
        }

        operator const ANew* () const
        {
            return ArrayOfTypes;
        }
};

But it gives me these errors:

C++\Types.h|12|error: invalid initialization of reference of type 'ANew&' from expression of type 'CustomType'|

C++\Types.h|17|error: cannot convert 'const std::vector<CustomType, std::allocator<CustomType> >' to 'const ANew*' in return|

I don't know if it's possible to overload those operators or if I'm doing it right.. Any help is appreciated.

Recommended Answers

All 5 Replies

Line 12 would have to return a reference to CustomType. As for line 17, I'm not sure what operator you want to overload. Currently you are returning a copy of the ArrayOfTypes (vector<CustomType>), but that is not what is in the return type of the function call.
What do you want those two functions to return? And what operator did you want to overload in line 15?

Line 15 is an implicit conversion operator. The return type is const ANew* , and so, you need to return that. As in:

operator const ANew* () const
        {
            return this;
        }

But I have to say that I don't approve of this implicit conversion from value to pointer, it is dangerous.

As for the call-operator, you need to the correct return-type:

CustomType& operator ()(int I)
        {
            return ArrayOfTypes[I];
        }

Adding to above, change this

ANew() : ArrayOfTypes(0) {}

to this

ANew(){}

The vector will be default constructed already

Follow what I was told above, I still cannot compile.. And can someone explain what mike means by "It's dangerous"? Why is it dangerous?

I plan to translate this to C# as soon as I learn how to fix it and why everything in C# is static -____-

The changes and additions now look like:

class ANew
{
    private:
        vector<CustomType> ArrayOfTypes;
        int rows;

    public:
        ANew() {}
        ~ANew() {}

        CustomType& operator ()(int I)
        {
            return ArrayOfTypes[I];
        }

        CustomType& operator [](int I)
        {
            return ArrayOfTypes[I];
        }

        operator const vector<CustomType> () const
        {
            return ArrayOfTypes;
        }

        int operator == (const ANew &AN)
        {
            return (ArrayOfTypes == AN.ArrayOfTypes);
        }

        int operator != (const ANew &AN)
        {
            return !(ArrayOfTypes == AN.ArrayOfTypes);
        }

        ANew& operator = (const CustomType& CT)         //Add the CustomType to ArrayOfTypes. Ex: ArrayOfTypes AN = CustomType X
        {
            if (this[LEN(this)] != &CT)			//#define LEN(a) (sizeof(a)/sizeof(*a))
            {
                this.push_back(CT);
            }
            return *this;
        }

        ANew& operator = (const ANew& AN)
        {
            if (this != &AN)
            {
                this = AN;
            }
            return *this;
        }
};

There are many problems with your code, here are some in-code comments:

class ANew
{
    private:
        vector<CustomType> ArrayOfTypes;
        int rows;

    public:
        ANew() {}
        ~ANew() {}

        CustomType& operator ()(int I)
        {
            return ArrayOfTypes[I];
        }

        CustomType& operator [](int I)
        {
            return ArrayOfTypes[I];
        }

        // You should not return a copy of the underlying vector, return a reference instead (notice the ampersand):
        operator const vector<CustomType>& () const
        {
            return ArrayOfTypes;
        }

        bool operator == (const ANew &AN) const // notice that this function should be const and should return a "bool" value.
        {
            return (ArrayOfTypes == AN.ArrayOfTypes);
        }

        bool operator != (const ANew &AN) const // ditto.
        {
            return !(ArrayOfTypes == AN.ArrayOfTypes);
        }

        // Don't use the = operator for doing an addition of an element to the array!
        //  Don't abuse operator overloading by redefining the semantics of the operator.
        //  The = operator means "assigning" not "inserting" or "adding an element".
        //  If you absolutely want an operator, use the << operator to add elements. 
        ANew& operator = (const CustomType& CT)         //Add the CustomType to ArrayOfTypes. Ex: ArrayOfTypes AN = CustomType X
        {
            //#define LEN(a) (sizeof(a)/sizeof(*a))
            // The LEN() macro doesn't make any sense.
            //  sizeof(this) will just be the size of a pointer on your computer. 
            //  sizeof(*this) is a fixed number (has nothing to do with the number of elements in the vector)
            // dividing those two gives a fixed and undefined value. 
            if (this[LEN(this)] != &CT)	 // here, you compare a pointer with an object!
            {
                this.push_back(CT);  // "this" is a pointer, so it should be used with this->something(). 
                                     //  and "this" does not have a member called "push_back()", you need to do this->ArrayOfTypes.push_back(CT).
            }
            return *this;
        }

        ANew& operator = (const ANew& AN)
        {
            if (this != &AN)  // Good!
            {
                this = AN;  // Shit! This is a recursive call to the same function (the assignment operator), this will yield an infinite recursion (infinite loop or even a stack overflow).
            }
            return *this;
        }
};

As per your question about the danger of an implicit conversion to a pointer. It is basically because pointers are dangerous when used carelessly (and implicit conversions are the most careless things around), such use is the root cause of most, if not all, problems with segmentation faults or access-violations (e.g. accessing memory that you shouldn't access), memory corruption (e.g. writing on memory that is not the memory you think it is, and corrupting something else in the code), and heap corruption (e.g. making the wrong requests for freeing or allocating memory from the heap, thus causing it to get corrupted, i.e. out-of-sync with the memory the heap is supposed to manage). You can read up more on why raw pointers are evil. Of course, that's an exaggeration, they have their uses, like reference-wrappers and as iterators (or for implementing iterators), but they should be handled with care, and should almost always be encapsulated. The underlying issue for them being a danger is essentially the fundamental issue of ownership, to know more, read my tutorial on the subject.

commented: TY =] Triumphost. +6
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.