compilation error with ctor

S

subramanian

Consider the following program:

#include <iostream>
#include <string>

class Member {
int x;
int y;
public:
Member(int argx, int argy);
Member(const Member &m);
void operator=(const Member &m);
};

Member::Member(int argx, int argy)
{
x = argx;
y = argy;
return;
}

Member::Member(const Member &m)
{
x = m.x;
y = m.y;
std::cout << "from copy ctor of Member class : x = " << x << " y = "
<< y << '\n';
return;
}

void Member::eek:perator=(const Member &m)
{
x = m.x;
y = m.y;
std::cout << "from operator= : x = " << x << " y = " << y << '\n';
return;
}

class Test {
public:
Test(const Member &argm1, const Member &argm2, const std::string
&val);
private:
std::string str;
Member member1;
Member member2;
};

Test::Test(const Member &argm1, const Member &argm2, const std::string
&val)
{
str = val;
member1 = argm1;
member2 = argm2;
std::cout << "from one arg ctor : " << str << '\n';
return;
}

int main(void)
{
Member argm1(10, 20);
Member argm2(100, 200);

Test tmp(argm1, argm2, "tmp object");

return 0;
}

If I compile this program with VC++ 2005 Express edition, it gives
compilation error at the line

Test::Test(const Member &argm1, const Member &argm2, const std::string
&val)

saying

'Member' : no appropriate default constructor available

Similar error occurs with g++ also.

If I change this ctor to

Test::Test(const Member &argm1, const Member &argm2, const std::string
&val) : member1(argm1), member2(arg2)
{
str = val;
std::cout << "from one arg ctor : " << str << '\n';
return;
}

then the compilation error goes. Though str is of class type
std::string, str = val is accepted. However the same does not hold for
class type Member for member1 = argm1 and member2 = argm2.
What is the difference ?
 
O

Ondra Holub

subramanian napsal:
Consider the following program:

#include <iostream>
#include <string>

class Member {
int x;
int y;
public:
Member(int argx, int argy);
Member(const Member &m);
void operator=(const Member &m);
};

Member::Member(int argx, int argy)
{
x = argx;
y = argy;
return;
}

Member::Member(const Member &m)
{
x = m.x;
y = m.y;
std::cout << "from copy ctor of Member class : x = " << x << " y = "
<< y << '\n';
return;
}

void Member::eek:perator=(const Member &m)
{
x = m.x;
y = m.y;
std::cout << "from operator= : x = " << x << " y = " << y << '\n';
return;
}

class Test {
public:
Test(const Member &argm1, const Member &argm2, const std::string
&val);
private:
std::string str;
Member member1;
Member member2;
};

Test::Test(const Member &argm1, const Member &argm2, const std::string
&val)
{
str = val;
member1 = argm1;
member2 = argm2;
std::cout << "from one arg ctor : " << str << '\n';
return;
}

int main(void)
{
Member argm1(10, 20);
Member argm2(100, 200);

Test tmp(argm1, argm2, "tmp object");

return 0;
}

If I compile this program with VC++ 2005 Express edition, it gives
compilation error at the line

Test::Test(const Member &argm1, const Member &argm2, const std::string
&val)

saying

'Member' : no appropriate default constructor available

Similar error occurs with g++ also.

If I change this ctor to

Test::Test(const Member &argm1, const Member &argm2, const std::string
&val) : member1(argm1), member2(arg2)
{
str = val;
std::cout << "from one arg ctor : " << str << '\n';
return;
}

then the compilation error goes. Though str is of class type
std::string, str = val is accepted. However the same does not hold for
class type Member for member1 = argm1 and member2 = argm2.
What is the difference ?

See
http://groups.google.com/group/comp...dd6693/8d07a2c131576a24?#doc_7dcd9695f701fc1f
It is explained there.

In fact you need default constructor for
class X
{
public:
X()
// Here is called default constructor of member
{
member = something;
}

private:
Member member;
};
 
R

Ron Natalie

subramanian said:
Test::Test(const Member &argm1, const Member &argm2, const std::string
&val) : member1(argm1), member2(arg2)
{
str = val;
std::cout << "from one arg ctor : " << str << '\n';
return;
}

then the compilation error goes. Though str is of class type
std::string, str = val is accepted. However the same does not hold for
class type Member for member1 = argm1 and member2 = argm2.
What is the difference ?
The issue has nothing to do with the assigment (str = val). The issue
is that you don't provide any initializers to the members when they
are constructed, so there needs to be a default constructor.

std::string has a default constructor.
Member doesn't.

If you want the behavior you are looking for, provide a default
construct to member. It could be as simple change as:

Member(int argx = 0, int argy = 0);


Other than the debug prints in the copy constuctor and copy
assignment operators, they do nothing that the implicitly
generated ones wouldn't have done (except for the unconventional
operator= returning void). If this is all they will ever do,
get rid of yours.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top