confusing errors

H

heng

#include<iostream>
#include<string>
using namespace std;

class A
{
public:
int x;
int y;
A(int y_){y=y_;}
};

int main()
{
A aobj;
return 0;
}

When I define an object, some data members cannot be initialized and no
appropriate default constructor is available. So, there is an error.

However, even if I add the default constructor explicitly, there are
still errors in the following code.

#include<iostream>
#include<string>
using namespace std;

class A
{
public:
int x;
int y;
A();
A(int y_){y=y_;}
};

int main()
{
A aobj;
return 0;
}

Why?
 
V

Victor Bazarov

heng said:
#include<iostream>
#include<string>
using namespace std;

class A
{
public:
int x;
int y;
A(int y_){y=y_;}

Prefer initialisation over assignment. See FAQ.
};

int main()
{
A aobj;
return 0;
}

When I define an object, some data members cannot be initialized and
no appropriate default constructor is available. So, there is an
error.

However, even if I add the default constructor explicitly, there are
still errors in the following code.

#include<iostream>
#include<string>
using namespace std;

class A
{
public:
int x;
int y;
A();
A(int y_){y=y_;}
};

int main()
{
A aobj;
return 0;
}

Why?

*What* errors?

V
 
N

Noah Roberts

heng said:
#include<iostream>
#include<string>
using namespace std;

class A
{
public:
int x;
int y;
A(int y_){y=y_;}
};

int main()
{
A aobj;
return 0;
}

When I define an object, some data members cannot be initialized and no
appropriate default constructor is available. So, there is an error.

Yes, that code will fail because there is no default constructor yet
you are attempting to use one.
However, even if I add the default constructor explicitly, there are
still errors in the following code.

#include<iostream>
#include<string>
using namespace std;

class A
{
public:
int x;
int y;
A();
A(int y_){y=y_;}
};

int main()
{
A aobj;
return 0;
}

Why?

This one will fail to link because there is no definition for your
default constructor.
 
H

heng

This one will fail to link because there is no definition for your
default constructor.

Do I need to define my default constructor? I think the default
constructor is always as follows:

class Foo
{
public:
Foo(); //default constructor
}
 
V

Victor Bazarov

heng said:
Do I need to define my default constructor? I think the default
constructor is always as follows:

class Foo
{
public:
Foo(); //default constructor
}

No. The default constructor is the one that *can be called* without
any arguments, not the one that doesn't have any arguments. Think
default argument values:

class Foo
{
public:
Foo(int a = 42); // defautl constructor
};

V
 
N

Noah Roberts

heng said:
Do I need to define my default constructor? I think the default
constructor is always as follows:

class Foo
{
public:
Foo(); //default constructor
}

That is a declaration, not a definition. There is an important
distinction. All that does is say Foo() exists...but if it isn't
defined somewhere then it doesn't actually exist.

The original code caused the default constructor to not be created by
creating a custom one. In other words,

class X {};

has a default constructor while,

class Y { Y(int x) {} };

does not.

With,

class Y {
Y(int x) {}
Y();
};

The compiler will hapily compile any code that uses the default
constructor for Y assuming it will find it somewhere later and be able
to link to it. If there is no

Y::Y() {}

in your code anywhere (certainly not in what you posted) then of course
it never finds it.
 
H

heng

Noah said:
class Y {
Y(int x) {}
Y();
};
So, in your code, the default constructor of Y is declared, but not
defined, hence it cannot be used by the compiler.

Right?
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

So, in your code, the default constructor of Y is declared, but not
defined, hence it cannot be used by the compiler.

Actually the compiler will be happy but the linker won't.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Thanks a lot. What's the role of the linker?

The compiler takes each .cpp-file and compiles it (before that the
pre-processor has expanded all your #includes into the file *) which
gives you an object-file, one for each .cpp-file. The linker than takes
all the object-files and puts them together into an executable. This is
good since when you change one .cpp-file you don't have to recompile all
the others, just the change one and then re-link it all.

* What the pre-processor does is to replace each #include-line with the
content of the file given, which can create quite large files. This
large file is a compilation-unit, which is what the compiler operates on.
 
H

heng

Thanks a lot.
The compiler takes each .cpp-file and compiles it (before that the
pre-processor has expanded all your #includes into the file *) which
gives you an object-file, one for each .cpp-file. The linker than takes
all the object-files and puts them together into an executable. This is
good since when you change one .cpp-file you don't have to recompile all
the others, just the change one and then re-link it all.

* What the pre-processor does is to replace each #include-line with the
content of the file given, which can create quite large files. This
large file is a compilation-unit, which is what the compiler operates on.
 

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

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,202
Latest member
MikoOslo

Latest Threads

Top