Now I want to know that, how the compiler locates the CElement's header file?

It does not, since you did not include the file. What you did sounds correct: the class definition was not needed, so you just declared the class instead of including the header file that contains the class definition.

Quote:

Originally Posted by execute

Try using the
Singleton Design Pattern for your classes that are needed in multiple files. (so you won't need forward class declaration)

No, that is bad advice. The singleton design pattern has nothing to do with needing to use a class name in multiple files.

Quote:

Originally Posted by execute

But if you are simply including one or two headers, just use

Incidentally, names that contain consecutive underscores are reserved to the implementation for any use.

12-04-2008

execute

Quote:

Originally Posted by laserlight

It does not, since you did not include the file. What you did sounds correct: the class definition was not needed, so you just declared the class instead of including the header file that contains the class definition.

No, that is bad advice. The singleton design pattern has nothing to do with needing to use a class name in multiple files.

Incidentally, names that contain consecutive underscores are reserved to the implementation for any use.

Singleton, can be used for a class that's used in multiple files and multiple classes. It doesn't hurt, but I suppose it's overkill.

By who, the C++ Deities? :P

12-04-2008

laserlight

Quote:

Originally Posted by execute

Singleton, can be used for a class that's used in multiple files and multiple classes. It doesn't hurt, but I suppose it's overkill.

No, the singleton design pattern is used when you need at most one object of a class throughout the program. Here manzoor is talking about needing to use a CElement pointer. There is no evidence to suggest that at most one CElement object may exist.

Quote:

Originally Posted by execute

By who, the C++ Deities? :P

In a way, if you consider the C++ standards committee the gods and goddesses of C++ ;)

12-04-2008

execute

Quote:

Originally Posted by laserlight

No, the singleton design pattern is used when you need at most one object of a class throughout the program. Here manzoor is talking about needing to use a CElement pointer. There is no evidence to suggest that at most one CElement object may exist.

In a way, if you consider the C++ standards committee the gods and goddesses of C++ ;)

Yes, one object true, but it can also be used in cases where you need to access variables throughout a large project, without having multiple instances of it. In order to keep it simple.

Though Singleton (as the name implies) is used in cases where we need to have one instance, it's not the only reason. Besides, I wasn't exactly understanding what the original poster wanted, he wasn't very clear, so I gave him options.

Ok, so _HEADER_ and __CPP__ ?
But how often do you ever #include, a .cpp anyway, imo, seems like a pretty useless standard :P.

12-04-2008

matsp

Quote:

Originally Posted by execute

Ok, so _HEADER_ and __CPP__ ?
But how often do you ever #include, a .cpp anyway, imo, seems like a pretty useless standard :P.

All names starting with _ and a capital is also reserved for the compiler. For example, the compiler already uses __LINE__, __FILE__, __DATE__ (I think) and various other __XXX__ names. Of coruse, if you have a "line.h" and you do "ifndef __LINE__ " it will not do anything, since __LINE__ is indeed defined by the compiler itself! So since you can't use this sort of name for SOME things, then you should not use it elsewhere either, because it becomes less consistent.

--
Mats

12-04-2008

laserlight

Quote:

Originally Posted by execute

Yes, one object true, but it can also be used in cases where you need to access variables throughout a large project, without having multiple instances of it. In order to keep it simple.

If you do not actually need to control the number of objects created, then that sounds like an abuse of the singleton pattern such that some people have called it the "singleton anti-pattern". Effectively, you would just be using a global variable. Instead of keeping it simple, the tight coupling would merely make maintenance more difficult.

Quote:

Originally Posted by execute

Besides, I wasn't exactly understanding what the original poster wanted, he wasn't very clear, so I gave him options.

Yeah, the question seems rather weird. manzoor basically asked how the compiler was supposed to find the header file, but the point is that the header file is not included since the forward declaration is used instead.

Quote:

Originally Posted by execute

Ok, so _HEADER_ and __CPP__ ?
But how often do you ever #include, a .cpp anyway, imo, seems like a pretty useless standard :P.

I think that you misinterpreted "implementation" to mean "source file". When the C++ Standard mentions "implementation", it means "compiler and standard library implementation", i.e., the names matching those conditions are reserved for use by C++ compiler writers and C++ standard library implementors.

Oh, and the full clause is: "Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use."

As such, you should also avoid defining the name _HEADER_, unless you happen to be writing a C++ compiler or standard library implementation.

12-04-2008

execute

Actually, you cannot define a global variable across multiple cpp files. It will give you redefinition errors. You may be able to do it, you'd have to be really careful. So for that sort of purpose, I either try not to use global variables, or worst case, I use singleton. And just because I don't use it as a "single object" as the primary purpose, doesn't mean it hurts anyone.

Fair Enough on the __ stuff.

12-04-2008

laserlight

Quote:

Originally Posted by execute

Actually, you cannot define a global variable across multiple cpp files. It will give you redefinition errors. You may be able to do it, you'd have to be really careful.

Ordinary global variables can be declared extern across header and source files and defined in exactly one source file.

Quote:

Originally Posted by execute

And just because I don't use it as a "single object" as the primary purpose, doesn't mean it hurts anyone.

It hurts the maintainer because it makes maintenance more difficult, for the same reason that global variables make maintenance more difficult. If you are not making use of the power to limit instantiation that the singleton pattern provides, then all you have is a glorified global variable. Some critics go as far as to argue that the singleton pattern is always an anti-pattern because of its close relation to global variables.

12-04-2008

execute

I never thought of that...
I use "extern" in importing functions from assembly into C... I guess I should have thought of it as a way to import other source file functions and global variables too.

Well, I guess since you can just do
extern void function();
extern int global;

Well then, I suppose you eliminated the singleton pattern... Oh and if we used struct's instead of classes, zomg, you eliminated C++. We can go backwards all the time. Just because there's a newer method of doing the same thing, doesn't make it bad :P.

"anti-pattern" that's hilarious, singleton does have its purpose, one instance, only one time. I suppose you can use a bunch of functions. But then again you can use assembly to code everything as well.

And I don't believe it hurts the maintainer, and I still cannot see where "global variables = bad" thing is coming from (it works great with interrupts), and the only downside is controlling the variables, but it's not a problem for seasoned programmers. Unless you are on an embedded system that is extremely low on memory, I don't see how "globals can be bad"... This is similar to the whole "making variables public is bad!", they exaggerate the downside. private, public, globals, are only made so that everything is easier to read, understand, and debug, not because it makes any difference to machine language.

Sometimes people take "common practices" too far.

12-04-2008

matsp

Globals are bad becuase it allows anything anywhere to use the variable, and if a variable is used a lot, it gets hard to know how and when it's used, and if you decide to change something related to that variable, it is more difficult than if it is a local variable that you can determine: Ok, it's only used here, here and here, so it is safe to do this. Global variables, on the other hand, may be used in MANY places, and it is much harder to know the relationships between their use, the functions that use it, and any change you plan to make in the global variable.

Public data members in classes are a related situation: Any code that uses the member variable will have to be changed if you change anything about the member variable. Let's say you have

Now, our pointy-haired boss have, for some unexplainable reason, decided:
1. We must change diameter to radius.
2. We can not change the size of the class (because there is other code that we do not want to "disturb" by recompiling).

If we had originally designed the class using getter/setter functions for diameter [1], we could hide the fact that we're now storing the radius, by simply multiplying by 2 in the getter, and dividing by 2 in the setter.

You may think "well, that doesn't matter, lets just recompile all the code" - which is fine if it's your own little project you are working on. But what if you have sold your library of gemetric calculations to a big customer, then you do not want to tell them "well, I've got a new version that is much better, particularly the circle functions are better, because we store the radius instead of the diameter <note: This is a salesman speaking, so any change is better> - but you have to recompile all the code that uses the library to make use of it". Well, if they have thousand and thousands of lines of code, in several dozen applications, some of which are written by third parties, they may not want to do that, so they say "Nah, we'll just stick with our trusty old one, so we won't pay for the new version" - which means that you (or your company) don't get the money for the new version you've just spent the last four months developing.

[1] Beware of inline functions: A previously compiled module that uses an inline function will just grab the data at the related address in the class - so it would get the radius instead of diameter. It's ok to use inline functions internally in the class itself, and for interfaces that absolutely won't change.

--
Mats

12-04-2008

phantomotap

Quote:

Well then, I suppose you eliminated the singleton pattern...

O_o

If you are only using the usual implementation strategy, 'some_class * some_class::get_shared_instance()', of the common singleton pattern as a means of controlling access to a non-unique instance of an object shared across a program you are not using the singleton pattern.

I get so tired of arguing this, but it isn't the interface, the implementation, or the name by which you call a construct that makes it fit or unfit for a particular purpose. The fact that there is an absolutely unique instance of an object is what makes it a singleton; the rest are just details.

If you don't need an absolutely unique instance of an object, you don't need a singleton. If no instance of an object is special in this way, you don't have a singleton. You just have a global instance of an object requiring an interface to access.

Soma

12-05-2008

laserlight

Quote:

Originally Posted by execute

Well then, I suppose you eliminated the singleton pattern.

If a singleton is not required then the singleton pattern is not applicable to begin with.

Quote:

Originally Posted by execute

Oh and if we used struct's instead of classes, zomg, you eliminated C++.

Of course, structs and classes are effectively the same, though the struct keyword is often conventionally reserved for POD structs.

Quote:

Originally Posted by execute

Just because there's a newer method of doing the same thing, doesn't make it bad :P.

Just because there's a newer method of doing the same thing does not make it good. As phantomotap pointed out, you are not actually using the singleton pattern if you are not working with a singleton.

Quote:

Originally Posted by execute

"anti-pattern" that's hilarious, singleton does have its purpose, one instance, only one time.

And I don't believe it hurts the maintainer, and I still cannot see where "global variables = bad" thing is coming from (it works great with interrupts), and the only downside is controlling the variables, but it's not a problem for seasoned programmers.

Related to matsp's explanation, global variables present another problem for seasoned programmers: it is more difficult to establish a proof of correctness for a program in the presence of global variables because global state can change in unexpected ways whenever a function is called. Unit testing also becomes more difficult since the various program units would be more tightly coupled.

Quote:

Originally Posted by execute

This is similar to the whole "making variables public is bad!", they exaggerate the downside. private, public, globals, are only made so that everything is easier to read, understand, and debug, not because it makes any difference to machine language.

Precisely: these language constructs exist to help programmers write code that "is easier to read, understand, and debug". I find it ironic that you accuse me of "going backwards all the time" and pointing out that I "can use assembly to code everything as well" when you insist that constructs more suited to assembly language be used in C++ without due consideration.

12-05-2008

execute

I'm not accusing anyone of going backwards, but you were saying that some argue Singleton is an "anti-pattern", and that just didn't make much sense.

@matsp, yes I know why they do it, it's just that they teach it so religiously, that people think "hmm I need a getter and setter for these 10 variables in this one file project!"

It should be emphasized that in team projects or large scale or medium scale projects, we shouldn't be making variables public, and/or using global variables when we can use local instead, or in databases, a singleton instead of a global extern.

@phantom, you have totally misunderstood what's going on.
1) Singleton has the ability to be one instance. It has the ability to be accessed across multiple files. Now I didn't think of using "extern" for that purpose, as I only use it when importing assembly functions.

So let's say I was using a singleton called:
CCommon::getInstance()->getDLL("c.dll");
I would use it in multiple files. And I only need one instance.

But laserlight was nice enough with extremely wise experience & expertise, that she recommended using "extern". So instead I could include "CCommon.h" and do:
extern void getDLL(string dll);

In let's say, 10 other files.

Well that sort of made the whole Singleton approach unnecessary. I don't really need a CCommon class, since my common functions can be accessed in multiple files now.

Having it as a singleton, doesn't do any damage, I am using one instance of it. So I was saying in a way, I could eliminate the singleton and do the same thing, and I can also do it with singleton, it's the same.