Re: help: class compile error
From: xuatla (xuatla_at_gmail.com)
Date: 07/09/04
- Next message: Chris: "Object Oriented Database for C++"
- Previous message: Arijit: "Re: Could Someone Help me on this CODE.... THANKS!!"
- In reply to: Victor Bazarov: "Re: help: class compile error"
- Next in thread: Howard: "Re: help: class compile error"
- Reply: Howard: "Re: help: class compile error"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Fri, 09 Jul 2004 13:56:14 -0700 To: "Victor Bazarov <v.Abazarov@comAcast.net>;John Harrison" <john_andronicus@hotmail.com>
Great. Thanks Victor Bazarov and John Harrison for the detail and
comprehensive explanation.
I corrected the code in your ways and now it goes through successfully.
I have some more questions about your answer.
>> CTest::CTest( const int &size )
>> {
>> iSize = size;
>> dElement = new double[iSize];
>
>
> Always prefer initialization over assignment. Read the FAQ.
What does this mean? Can I do the initialization and assignment in other
way? Where can I get FAQ? Can you tell me how to get the "help" file for
c++ grammar. Not man g++ but the grammar help of c++. I mean the on disk
help.
>
>> for ( int i = 0; i < iSize; i++ ) dElement[i] = 0.0;
>> }
>>
>> // copy operator
>> CTest CTest::operator = ( CTest &t2 )
>> { // <======== line 49
>> if ( iSize != t2.size() ) // reallocate the memory
>
>
> What if it's smaller? Is there still the need to reallocate?
If the size is smaller, then I can just change iSize but leave the
dElement unchanged. But what I concern is that if I don't release
dElement and reallocate it, then it may waste the memory. For example,
suppose
t1 = t2; //t1.size() = 100, t2.size() = 2;
then t1.dElement still occupies 100 double. Is it correct?
I designed this class because I am not familiar with "vector" in C++ and
I need to use this type frequently. In my code it's rare that the size
is decreased.
>
>> {
>> iSize = t2.size();
>> if (dElement) delete [] dElement;
You mentioned that I dont need to judge whether dElement is NULL before
deleting it. Is true for all types pointer?
>> dElement = new double[iSize];
>> }
>>
>> for ( int i = 0; i < iSize; i++ ) dElement[i] = t2[i];
Now I know that I need to use t2.dElement[i] instead of t2[i] here. If I
use t2[i], then compile error: no operator [] for const CTest&.
>
>
if I use #include "iostream.h", then compiler will give the warning of
"deprecated or antiquated header". But it's just a warning and compile
still completed. I changed to the following as you suggested.
#include <iostream>
using namespace std;
Do I need to add "using namespace" always for such a head file usage?
Another question for the class. I tried to use "const CTest&" but failed
and was told I didn't define the const class type (now I learned from
your explanation). Then I tried the following
class CTest
{
.....
} const;
What's the meaning of such "const" class?
One more question about new and delete:
I use new to create a CTest. And then delete it. But it seems that the
deletion is not successful. When I print it, it's still there.
Do I need to define new and delete for class by myself?
// main function
int main(void)
{
int N = 10;
CTest t1(N);
int i;
for ( i = 0; i < N; i++ ) t1[i] = i;
CTest *t2 = new CTest;
*t2 = t1;
for ( i = 0; i < N; i++ ) cout << (t1+*t2)[i] << endl;
delete t2;
for ( i = 0; i < N; i++ ) cout << (*t2)[i] << endl;
// still print out t2.
return 1;
}
Thanks a lot for your kind help!
X
Victor Bazarov wrote:
> xuatla wrote:
>
>> I encountered the following compile error of c++ and hope to get your
>> help.
>>
>> test2.cpp: In member function `CTest CTest::operator+=(CTest&)':
>> test2.cpp:79: error: no match for 'operator=' in '*this =
>> CTest::operator+(CTest&)((+t2))'
>> test2.cpp:49: error: candidates are: CTest CTest::operator=(CTest&)
>> make: *** [test2.o] Error 1
>>
>> I don't know why in the main function, "t2 = t1" is ok, but in the
>> operator += body, "*this = *this+t2" is wrong. What I am thinking is
>> that the compiler looks for *this+t2 first, which generate a new CTest
>> instance, and then copy to *this. What's the mistake I made?
>>
>> The code is compiled succeedly in Visual C++. but not in linux g++
>> (3.3.3).
>>
>> And also in Visual C++,
>> for ( int i = 0; ... ;.... )
>> defines a global int i. so I can use
>> for ( int i = 0; ... ;.... ) { ... }
>> for ( i = 0; ...;......) { ... }
>> but in linux g++, this is wrong. "i" is only alive in the for body. I
>> need to define "i" again in the 2nd for body. What's the update of
>> this grammar? Which one is the standard c++?
>
>
> If a variable is declared in the for statement, its scope is limited
> to the for statement and its body. VC++ has it as "an extension",
> otherwise known as the "for scope bug".
>
>>
>> Thank you very much in advance for the help.
>>
>> X
>>
>> -----------------------------------------------------
>> source code below:
>>
>> #include <iostream.h>
>
>
> There is no such standard header. Use <iostream>
>
>>
>> class CTest
>> {
>> private:
>> int iSize;
>> double *dElement;
>>
>> public:
>> CTest( const int &size = 1);
>
>
> Integers and other built-in types are usually better passed by
> value. It's much simpler to understand:
>
> CTest(int size = 1);
>
>> CTest( CTest &t );
>
>
> Copy constructors _usually_ accept their arguments by a _const_
> reference, unless they somehow _change_ the arguments.
>
>
> CTest(CTest const&);
>
>> ~CTest();
>>
>> public:
>> CTest operator = ( CTest &t2 );
>
>
> The _conventional_ operator= should return a _reference_ and also
> take its argument by a _const_ reference (unless it intends to change
> it somehow).
>
> CTest& operator=(CTest const &);
>
>> const int size(void) { return iSize; }
>
>
> Return value's cv-qualifiers are usually meaningless (and are not
> used anyway). A member function that doesn't (and never should)
> change its object should be declared 'const':
>
> int size() const { return iSize; }
>
>> double &operator[]( const int &index ) { return dElement[index]; }
>
>
> Again, passing a built-in type by reference is unnecessary:
>
> double& operator[](int index) { return dElement[index]; }
>
>>
>> public:
>> CTest operator + ( CTest &t2 );
>
>
> Any operator that doesn't change its operands should take those
> operands as 'const':
>
> CTest operator +(CTest const& t2) const;
>
>> CTest operator += ( CTest &t2 );
>
>
> Assignment operators _usually_ return a reference and if argument
> is not intended to be changed, it should be const:
>
> CTest& operator += (CTest const &t2);
>
>> };
>>
>> // constrution
>> CTest::CTest( const int &size )
>> {
>> iSize = size;
>> dElement = new double[iSize];
>
>
> Always prefer initialisation over assignment. Read the FAQ.
>
>> for ( int i = 0; i < iSize; i++ ) dElement[i] = 0.0;
>> }
>>
>> // copy constrution
>> CTest::CTest( CTest &t2 )
>
>
> See above about the change in the signature.
>
>> {
>> iSize = t2.size();
>> dElement = new double[iSize];
>
>
> Same here -- initialise, not assign.
>
>> for ( int i = 0; i < iSize; i++ ) dElement[i] = t2[i];
>
>
> You have full access to 't2's contents, why make additional calls
> to the operator[] here, when you simply could do
>
> ....... dElement[i] = t2.dElement[i];
>
> ?
>
>> }
>>
>> // destruction: release the allocated memory
>> CTest::~CTest()
>> {
>> if (dElement) delete[] dElement;
>
>
> No need to check for 'dElement's non-NULL-ness, just delete[].
> Deleting a null pointer has no effect.
>
>> }
>>
>> // copy operator
>> CTest CTest::operator = ( CTest &t2 )
>> { // <======== line 49
>> if ( iSize != t2.size() ) // reallocate the memory
>
>
> What if it's smaller? Is there still the need to reallocate?
>
>> {
>> iSize = t2.size();
>> if (dElement) delete [] dElement;
>> dElement = new double[iSize];
>> }
>>
>> for ( int i = 0; i < iSize; i++ ) dElement[i] = t2[i];
>
>
> Again, you can access t2.dElement directly, no need to call the
> operator[] for t2.
>
>> return *this;
>> }
>>
>> CTest CTest::operator + ( CTest &t2 )
>
>
> The type of function should change and the type of its argument.
> See above.
>
>> {
>> if ( iSize != t2.size() )
>> { // errorhandle
>> return *this; // to be changed
>> }
>>
>> CTest sum(t2);
>>
>> for ( int i = 0; i < iSize; i++ ) sum[i] += dElement[i];
>
>
> Again, you could simply access sum.dElement directly here.
>
>>
>> return sum;
>> }
>>
>> CTest CTest::operator += ( CTest &t2 )
>
>
> The return value type should change and the argument type. See
> above.
>
>> {
>> *this = *this + t2; // <===== line 79. compile error
>>
>> return *this;
>> }
>>
>> // main function
>> main(void)
>
>
> There are no implicit return types in C++.
>
> int main()
>
>> {
>> int N = 10; CTest t1(N);
>>
>> for ( int i = 0; i < N; i++ ) t1[i] = i;
>> CTest t2;
>>
>> t2 = t1;
>> for ( int i = 0; i < N; i++ ) cout << (t1+t2)[i] << endl;
>> return 1;
>> }
>
>
> Fix it all up as I recommend and see if the error goes away.
>
> Victor
- Next message: Chris: "Object Oriented Database for C++"
- Previous message: Arijit: "Re: Could Someone Help me on this CODE.... THANKS!!"
- In reply to: Victor Bazarov: "Re: help: class compile error"
- Next in thread: Howard: "Re: help: class compile error"
- Reply: Howard: "Re: help: class compile error"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|