473,395 Members | 1,969 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

class hate

Alright .... this makes no sense ...

Declared a class 'diskStorage' in a header ...diskStorage.h
Defined it's contructor and methods ... in diskStorage.cpp

Included diskStorage header in a another class ...(server.h)
and then tried to declare a variable of type 'diskStorage' ...
like this ( inside server.h )

diskStorage local_disk;

this is what I get
"error: no matching function for call to `diskStorage::diskStorage()"

Now, when I do this in the second class header file:
diskStorage* local_disk;

and then in the second class c o n t r u c t o r:
local_disk= new diskStorage(cylinders,tracks,track_time);

it compiles and behaves....except ...
calling local_disk->get_info() returns what it should o n l y in the
'server' class contructor.

when I call the local_disk->get_info() in a method that is part of
server class and not in it's constructor.... it returns garbage ...

I'm guessing the local_disk in the second case went out of scope.
But why does it not like me declaring a variable of type 'diskStorage'
in the first place?

Do I need to do this in the header file
diskStorage local_disk(); ////// would this not be a function !? and
not a variable

Dunno ...
Any ideas ?
---- server.h -----

#include "diskStorage.h"

class server
{
private:
diskStorage local_disk; // should server not know what
diskStorage is ?
}
---- diskStorage.h-------
class diskStorage {
protected:
u_long _cylinder_count;
u_long _sector_count;
u_long _track_time;
unsigned char geometry[12];

public:
//! class constructor
diskStorage(u_long cylinders,u_long sectors,u_long track_time);
~diskStorage();

void get_info();
};
--- diskStorage.cpp ----

#include "diskStorage.h"

diskStorage::diskStorage(u_long cylinders, u_long sectors, u_long
track_time)
{
_cylinder_count = cylinders;
_sector_count = sectors;
_track_time = track_time;

cout<<"Cylinders :"<< _cylinder_count<<endl;
cout<<"Sectors :" << _sector_count <<endl;
}
--- server.cpp---

server::server(u_long cylinders, u_long sectors, u_long track_time)
{
diskStorage local_disk(cylinders,sectors,track_time);//this does not
work
local_disk = new diskStorage(cylinders,sectors,track_time);//this does
work

}

I was sure I could declare a variable of any type in a header and
initialize it in elsewhere
Just like I can with any data type...but I seem to be wrong ...
Or just looked at the code for too long and missing something trivial.
These are of course just parts of the code but the rest is not relevant
and quite a mess.

The questions you may ask:
Q: Why am I separating class declarations and definitions?
A: 'Cause I hope to work on a project big enough (some day) where that
makes sense and am trying to get used to the idea.

Q: Why did I not look for examples ?
A: I did, but found nothing similar.

Q: Am I just trying to have someone else do my HW?
A: No, I need to learn b e f o r e someone asks me to do this (at
work).

btw. gdb tracing did not break where I told it to ... so now I'm
completely lost :-)

Nov 22 '06 #1
17 1548
On 21 Nov 2006 17:19:05 -0800 in comp.lang.c++, "Amchi"
<am*********@gmail.comwrote,
>diskStorage local_disk;

this is what I get
"error: no matching function for call to `diskStorage::diskStorage()"
diskstorage has no constructor that takes no arguments (also known as a
'default' constructor.) For a simple diskstorage variable as written,
you must supply arguments for initialization.

diskStorage local_disk(cylinders,tracks,track_time);
>Do I need to do this in the header file
diskStorage local_disk(); ////// would this not be a function !? and
not a variable
You're right, that's a function.

The class member is:

diskStorage local_disk;

It's initialized in the constructor initialization list as

server::server(u_long cylinders, u_long sectors, u_long track_time)
: local_disk(cylinders,sectors,track_time)
{
...

This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[10.6] Should my constructors use "initialization lists" or
"assignment"?" It is always good to check the FAQ before posting.
You can read the FAQ at:
http://www.parashift.com/c++-faq-lite/

Nov 22 '06 #2
Thank you.
Worked around it by changing the constructor to be empty and defined a
'mutator' method.

I appreciate you taking time to help.
Thanks again.
David Harmon wrote:
On 21 Nov 2006 17:19:05 -0800 in comp.lang.c++, "Amchi"
<am*********@gmail.comwrote,
diskStorage local_disk;

this is what I get
"error: no matching function for call to `diskStorage::diskStorage()"

diskstorage has no constructor that takes no arguments (also known as a
'default' constructor.) For a simple diskstorage variable as written,
you must supply arguments for initialization.

diskStorage local_disk(cylinders,tracks,track_time);
Do I need to do this in the header file
diskStorage local_disk(); ////// would this not be a function !? and
not a variable

You're right, that's a function.

The class member is:

diskStorage local_disk;

It's initialized in the constructor initialization list as

server::server(u_long cylinders, u_long sectors, u_long track_time)
: local_disk(cylinders,sectors,track_time)
{
...

This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[10.6] Should my constructors use "initialization lists" or
"assignment"?" It is always good to check the FAQ before posting.
You can read the FAQ at:
http://www.parashift.com/c++-faq-lite/
Nov 22 '06 #3
On 22 Nov, 04:23, "Amchi" <amer.ter...@gmail.comwrote:
Thank you.
Worked around it by changing the constructor to be empty and defined a
'mutator' method.
I'd like to point out (if you did not already know) that you can have
two (or more) constructors, one that takes no arguments, and one that
does. So you could keep your constructor and just create a new one that
creates a diskStorage with some default values.

PS. Next time, write your reply below that which you are replying to.
People get annoyed if you don't.

--
Erik Wikström

Nov 22 '06 #4

er****@student.chalmers.se wrote:
On 22 Nov, 04:23, "Amchi" <amer.ter...@gmail.comwrote:
Thank you.
Worked around it by changing the constructor to be empty and defined a
'mutator' method.

I'd like to point out (if you did not already know) that you can have
two (or more) constructors, one that takes no arguments, and one that
does. So you could keep your constructor and just create a new one that
creates a diskStorage with some default values.
Had a nightmare about it and in the middle of the night realized I
could have done that.
Stepping back and forgetting about it for a moment would have helped.
PS. Next time, write your reply below that which you are replying to.
People get annoyed if you don't.
Ok. My bad.

Nov 22 '06 #5
---- server.h -----

#include "diskStorage.h"

class server
{
private:
diskStorage local_disk; // should server not know what
diskStorage is ?
}

I don't know if you've omitted them because you're posting to a newsgroup,
but you should have inclusion guards in header files:

#ifndef INC_SERVER_HPP
#define INC_SERVER_HPP

/* Contents of Header file */

#endif

By the way, I advocate the "hpp" extension for C++ header files, an "h" for
C header files. (Same goes for "cpp" and "c").

---- diskStorage.h-------
class diskStorage {
protected:
u_long _cylinder_count;
u_long _sector_count;
u_long _track_time;
unsigned char geometry[12];

public:
//! class constructor
diskStorage(u_long cylinders,u_long sectors,u_long track_time);
~diskStorage();

void get_info();
};

--- diskStorage.cpp ----

#include "diskStorage.h"

diskStorage::diskStorage(u_long cylinders, u_long sectors, u_long
track_time)
{
_cylinder_count = cylinders;
_sector_count = sectors;
_track_time = track_time;

cout<<"Cylinders :"<< _cylinder_count<<endl;
cout<<"Sectors :" << _sector_count <<endl;
}

You might prefer use of an "constructor initialiser list" here. If you
don't know what that is, Google for it.

--

Frederick Gotham
Nov 22 '06 #6
Frederick Gotham schrieb:
>---- server.h -----

#include "diskStorage.h"

class server
{
private:
diskStorage local_disk; // should server not know what
diskStorage is ?
}


I don't know if you've omitted them because you're posting to a newsgroup,
but you should have inclusion guards in header files:

#ifndef INC_SERVER_HPP
#define INC_SERVER_HPP

/* Contents of Header file */

#endif

By the way, I advocate the "hpp" extension for C++ header files, an "h" for
C header files. (Same goes for "cpp" and "c").
Yes, this is absolutely wise.
By the way, to add some confusion to a C++ learner, let me add that in
the above case (in "server.h") you could (and imho should) use a class
forward declaration. If a class name is used only as parameter or return
value or member it is not necessary to include the header, it's ok to
add a line
class diskStorage;
and the compiler is perfectly happy. Try it ;)
Some of my colleagues swear that this makes loading time shorter, but I
never noticed that - maybe my projects were too few files....

Jan
Nov 23 '06 #7
Jan Bornschlegel wrote:
Frederick Gotham schrieb:
>>---- server.h -----

#include "diskStorage.h"

class server
{
private:
diskStorage local_disk; // should server not know what
diskStorage is ?
}


I don't know if you've omitted them because you're posting to a
newsgroup, but you should have inclusion guards in header files:

#ifndef INC_SERVER_HPP
#define INC_SERVER_HPP

/* Contents of Header file */

#endif

By the way, I advocate the "hpp" extension for C++ header files, an
"h" for C header files. (Same goes for "cpp" and "c").

Yes, this is absolutely wise.
By the way, to add some confusion to a C++ learner, let me add that in
the above case (in "server.h") you could (and imho should) use a class
forward declaration. If a class name is used only as parameter or return
value or member it is not necessary to include the header, it's ok to
add a line
Not quite true. If it's used as a param, return value, or *pointer or
reference* member, it's not necessary to include the header. If it's
used as a regular member, it is necessary. Otherwise, how would the
compiler know how much memory to allocate for (in the example) the servr
class?
Nov 23 '06 #8

Frederick Gotham wrote:
By the way, I advocate the "hpp" extension for C++ header files, an "h" for
C header files. (Same goes for "cpp" and "c").
I use .hpp for exported headers, .hxx for private headers.

A private header is one that is not used outside of its module. (A
module here meaning a group of classes that implement functionality
that are reasonably well coupled together).

Nov 23 '06 #9

Amchi wrote:

< snip down to the code >
>
---- server.h -----

#include "diskStorage.h"

class server
{
private:
diskStorage local_disk; // should server not know what diskStorage is ?
}
I don't know at this point what diskStorage is or what server is but
this class hides nothing because anyone including server.h is
indirectly including diskStorage.h as well.

Better is generally to reduce the coupling by using a foward
declaration. This is often done with a "pImpl" class.

If using boost, one way here is to use scoped_ptr so:

class server
{
private:
boost::scoped_ptr< diskStorage local_disk;

// plus public interface, of course
};

You have to include the boost/scoped_ptr header to do this but you can
forwardly declare diskStorage here, including the header only in the
server.cpp.

Assuming that everyone is using boost regularly, it will not be
increasing the coupling by including the boost header.

If you do not want to add a dependency on boost for those using the
class (eg you are exporting it) then you can use a raw pointer, but you
have to manage it yourself (as well as managing copying and
assignment).
---- diskStorage.h-------
class diskStorage {
protected:
u_long _cylinder_count;
u_long _sector_count;
u_long _track_time;
unsigned char geometry[12];
These should probably be private rather than protected. Magic numbers
(like 12) should normally be "enum"ed.
The questions you may ask:
Q: Why am I separating class declarations and definitions?
A: 'Cause I hope to work on a project big enough (some day) where that
makes sense and am trying to get used to the idea.
And also it's usually a sensible thing to do. The only main exceptions
are
1. when writing templates (because most compilers don't support export)
2. Writing something very generic that you want to be able to include
from multiple projects without having to link against anything
3. Writing a very trivial class, often a functor.

I also sometimes writing implementation classes with no header file at
all, and these are then sometimes exported as symbols but that's
another issue.

Nov 23 '06 #10
>Yes, this is absolutely wise.
By the way, to add some confusion to a C++ learner, let me add that in
the above case (in "server.h") you could (and imho should) use a class
forward declaration. If a class name is used only as parameter or return
value or member it is not necessary to include the header, it's ok to
add a line

Not quite true. If it's used as a param, return value, or *pointer or
reference* member, it's not necessary to include the header. If it's
used as a regular member, it is necessary. Otherwise, how would the
compiler know how much memory to allocate for (in the example) the servr
class?
As long as you include the .h file in the implementing (.cpp) file?
My compilers never complained these things, but I never use inline
constructors, maybe that's the reason.
Dec 7 '06 #11

Jan Bornschlegel wrote:
Yes, this is absolutely wise.
By the way, to add some confusion to a C++ learner, let me add that in
the above case (in "server.h") you could (and imho should) use a class
forward declaration. If a class name is used only as parameter or return
value or member it is not necessary to include the header, it's ok to
add a line
Not quite true. If it's used as a param, return value, or *pointer or
reference* member, it's not necessary to include the header. If it's
used as a regular member, it is necessary. Otherwise, how would the
compiler know how much memory to allocate for (in the example) the servr
class?

As long as you include the .h file in the implementing (.cpp) file?
My compilers never complained these things, but I never use inline
constructors, maybe that's the reason.
You're using some interesting compilers then because without the
information necissary to know how to construct an object's members you
don't know enough to construct it. In C++ any time you use an object
you need to know its memory layout. You can't know this if you don't
know the layout of its members.

So, as long as you happen to include the member's h file in every cpp
file that uses the main object you will be ok...as long as you include
it first...but then you may as well just include the member's h file in
the object's h file and make sure you never forget because you gain
nothing by not doing so.

Dec 7 '06 #12

"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@j72g2000cwa.googlegro ups.com...
So, as long as you happen to include the member's h file in every cpp
file that uses the main object you will be ok...as long as you include
it first...but then you may as well just include the member's h file in
the object's h file and make sure you never forget because you gain
nothing by not doing so.
Except a lot of extra time compiling. I think you should only
include headers in headers when you have to and use
forward declarations when you can.
Dec 7 '06 #13

Duane Hebert wrote:
"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@j72g2000cwa.googlegro ups.com...
I've added a bit more context from up-thread:

<quote Jan Bornshclegel>
If a class name is used only as parameter or return
value or member it is not necessary to include the header, it's ok to
add a [forward declaration]
</quote>
So, as long as you happen to include the member's h file in every cpp
file that uses the main object you will be ok...as long as you include
it first...but then you may as well just include the member's h file in
the object's h file and make sure you never forget because you gain
nothing by not doing so.

Except a lot of extra time compiling. I think you should only
include headers in headers when you have to and use
forward declarations when you can.
While being very sensible advice, I think that's a different point.
Let's have two headers:

// a.h start
class A {};
// a.h end

// b.h start
class B
{
A a;
};
// b.h end

Classes A and B are defined in separate headers. Class B has a member
of type A. Given the above, this program will not compile

#include "b.h"
int main() {}

The compiler complains at the A member in class B because it does not
know what A is. I read Jan's quote above to be suggesting that a
forward declaration would fix that, but adding the forward declaration
class A; to the top of b.h does not help here.

What does help is to include a.h *before b.h* in the program, so this
will compile (without any forward declaration in b.h)

#include "a.h"
#include "b.h"
int main() {}

However, as Noah says, if you need to do this to make the program
compile, you should move the inclusion of a.h into b.h so that users of
class B only need to include one header.

You are absolutely right that including headers in other headers when
it's not necessary can lead to extra compile time, but as I read Noah's
comments he was referring to the situation where it *is* necessary to
include one header in another.

Gavin Deane

NB: In the real world, the headers should have include guards, but I
left them out here to avoid confusion as they have no effect on my
example.

Dec 8 '06 #14

"Gavin Deane" <de*********@hotmail.comwrote in message
news:11*********************@73g2000cwn.googlegrou ps.com...
While being very sensible advice, I think that's a different point.
Let's have two headers:

// a.h start
class A {};
// a.h end

// b.h start
class B
{
A a;
};
// b.h end

Classes A and B are defined in separate headers. Class B has a member
of type A. Given the above, this program will not compile

#include "b.h"
int main() {}

The compiler complains at the A member in class B because it does not
know what A is. I read Jan's quote above to be suggesting that a
forward declaration would fix that, but adding the forward declaration
class A; to the top of b.h does not help here.
What does help is to include a.h *before b.h* in the program, so this
will compile (without any forward declaration in b.h)

#include "a.h"
#include "b.h"
int main() {}
Right. Creating a member like:
A a;

the compiler needs to know the size of the object
and it can't get that from a forward declaration.
I didn't catch that bit up thread.
However, as Noah says, if you need to do this to make the program
compile, you should move the inclusion of a.h into b.h so that users of
class B only need to include one header.
Ok.
You are absolutely right that including headers in other headers when
it's not necessary can lead to extra compile time, but as I read Noah's
comments he was referring to the situation where it *is* necessary to
include one header in another.
Yep. I should have gone back through the thread. I've just finished
going through a rather large project and fixing stuff like this so
this caught my attention <g>
Dec 8 '06 #15

Duane Hebert wrote:
"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@j72g2000cwa.googlegro ups.com...
So, as long as you happen to include the member's h file in every cpp
file that uses the main object you will be ok...as long as you include
it first...but then you may as well just include the member's h file in
the object's h file and make sure you never forget because you gain
nothing by not doing so.

Except a lot of extra time compiling. I think you should only
include headers in headers when you have to and use
forward declarations when you can.
You gain no compile time discount by including header A everywhere you
include header B vs. including header A in header B. Any time header A
changes it will require all cpp files that include it to recompile
whether they include it directly or by including a header that does.

Dec 8 '06 #16
Gavin Deane schrieb:
[...]

The compiler complains at the A member in class B because it does not
know what A is. I read Jan's quote above to be suggesting that a
forward declaration would fix that, but adding the forward declaration
class A; to the top of b.h does not help here.
Hej,

You're right, I looked at my code example again and its all pointers and
references I used, so the compiler never needed to know sizes.
[By the way, this code was compiled with VC7 on W2K and gcc (don't ask
me for versions) on a SuSE 9.3 machine.]

Of course a forward declaration is *not* sufficient to tell the compiler
sizes, but since it has to know A's size before allocating memory for B,
A must be known.

I usually aviod these problems by using pointers wherever I can ;)

So please forget what I said before, it's not correct.
However, for parameters and return values and *pointers* it's still ok
to use forward declarations.
Plus, from a beginner's point of view, you don't need to crawl through
thousands of headers recursively if you want to understand what a
program does that you didn't write yourself and which is documented as
good as most projects I know - which is *not at all* (just useless
comments like "int res; //an integer for the result"

Jan
Dec 8 '06 #17

"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@j44g2000cwa.googlegro ups.com...
>Except a lot of extra time compiling. I think you should only
include headers in headers when you have to and use
forward declarations when you can.

You gain no compile time discount by including header A everywhere you
include header B vs. including header A in header B. Any time header A
changes it will require all cpp files that include it to recompile
whether they include it directly or by including a header that does.
No but that's not what I said. My point was to use forward
declarations in header files when possible. I jumped in this
thread too late it seems.

As to whether to include A.h in B.h so users don't need to
include both, I'm not so sure. You're right that it doesn't matter
as far as compile time but I usually try to include all
required headers in my cpp file. I've had to fix too many problems
where some class was removed and other classes were depending
on it to get some other header.

This is even true with std headers. For example, including iostream
and using std::endl. This doesn't work on all compilers.
Dec 8 '06 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Jon | last post by:
Hello all, I'm certain this question has been asked before; I was unsure what terms to search for within the newsgroup archive to find the proper answer I wanted. Hopefully someone can point me...
13
by: Bryan Parkoff | last post by:
I have created three classes according to my own design. First class is called CMain. It is the Top Class. Second class and third class are called CMemory and CMPU. They are the sub-classes....
3
by: Bob | last post by:
In C++, default access is private. In Java, default access is package. In C++, default access is ___________ ??
0
by: Rick | last post by:
We have an class sent to us by a vendor in a .h file. This class controls access to a subsystem for gathering data. Currently we are using C++ 6.0 to access this class. Now we want to move to .net....
16
by: Allen | last post by:
I have a class that returns an arraylist. How do I fill a list box from what is returned? It returns customers which is a arraylist but I cant seem to get the stuff to fill a list box. I just...
10
by: Bonzol | last post by:
vb.net Hey there, could someone just tell me what the differnce is between classes and modules and when each one would be used compared to the other? Any help would be great Thanx in...
5
by: Slant | last post by:
Here's a question that most will have different answers to. I'm just dying to find a solution that seems halfway automated!! There really are two seperate issues which might be answered by the...
9
by: jerry.upstatenyguy | last post by:
I am really stuck on this. I am trying to write a string array containing a "word" and a "definition" to a class called Entry. Ultimately this will end up in another class called dictionary. No,...
7
by: Tamagafk | last post by:
error_reporting(E_ALL); class cls{ var $val; function cls(){ $this->$val = 999; } } $c = new cls; With error_reporting set to E_ALL PHP floods me with notifications that
6
by: Marvin Barley | last post by:
I have a class that throws exceptions in new initializer, and a static array of objects of this type. When something is wrong in initialization, CGI program crashes miserably. Debugging shows...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.