C++ what to code if i put a class after main() function - c++

I'm watching some video tutorials on C++ and i know you must define a function / class before it is used or called. But I like having my main() function at the top, and everything else below the main function. I know if i define a function below the main function I must declare it before it is used, but what about a class? What do I need to put above my main function to use my class below the main function.
#include <iostream>
using namespace std;
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
I tried defining my class by placing this right before main():
class ClassOne;
but it doesn't work.

This is why header files are normally used in C++. When you're saying ClassOne one, the compiler needs to know what the class looks like to create an object of that type. It's not enough to know that the class exists somewhere (that is enough if all you want is a pointer). So the compiler needs to already have read the definition of the class.
Your class has to be defined before it is first used. Without putting it explicitly before main, the usual way is to create a header file. So you create ClassOne.h with the class declaration, and you have #include "ClassOne.h at the top of your file. In this situation the actual methods of the class would normally be in another source file, ClassOne.cpp.

A class MUST be "complete" when you create an instance of it. So there is no way you can use the class before you have defined the whole content of the class.
It is possible to do something like this:
class ClassOne;
ClassOne* make_class_one();
void use_class(ClassOne *x);
int main()
{
ClassOne* one = make_class_one();
use_class(one);
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
ClassOne* make_class_one()
{
return new ClassOne; // Bad idea, use uniqe_ptr, but I'm lazy.
}
void use_class(ClassOne *x)
{
x->coolSaying();
}
But in general, we don't want to do that.

One scenario where the class definition after the main() function makes sense:
#include <iostream>
using namespace std;
void f();
int main()
{
f();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
void f()
{
ClassOne one;
one.coolSaying();
}

(note: all other answers are correct, but you may find this useful)
I discovered this idiom to invert the order of main and secondary function classes. I use to share small code with colleagues, everybody expects the core of the code (i.e. main) to be on top so they can edit it quickly. It works with classes and functions (without need of declaration) of course. Usually I can leave the preamble (first #includes) because those have include guards in most cases.
#include <iostream>
using namespace std;
#ifdef please_see_definitions_below_main
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
#else
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
#define please_see_definitions_below_main
#include __FILE__
#endif
I use the tag please_see_definitions_below_main so it serves as comment also, but if you don't like it you can use something shorter, like AFTER.

You cannot create an actual instance of the type (variable, value member) until the type is fully defined, as its size is not known. There is no way around that, but there is a lot you can already do with a pointer to an incomplete type.

Related

trouble with accessing a class from a different class

just started to learn c++.I'm trying new things in c++ on thing i wanted to try is to access a class from another class and change its instances and print its instance on screen.
I would like to know 2 things 1)whats wrong with my code 2)where should i declare class declarations (in main file or class definition file?)
here is the error log -
'object::carrier' uses undefined class 'sub'
'cout': is not a member of 'std'
'cout': undeclared identifier
this is what i came up with-
source.h
#include <iostream>
#include <vector>
#include "stuff.h"
int main()
{
object spoon(3);
spoon.get();
}
stuff.cpp
#pragma once
#include <vector>
class object;
class sub;
class object
{
private:
std::vector <sub> thing;
public:
object(int n);
void get() const;
};
class sub
{
private:
int num;
public:
void set_num(int n);
};
stuff.cpp
#include <vector>
#include "stuff.h"
// methods for object
object::object(int n)
{
sub carrier;
carrier.set_num(n);
}
void object::get() const
{
std::cout << carrier.num;
}
// methods for sub
void sub::set_num(int temp_num)
{
num = temp_num;
}
thanks
In your object class, specifically object::get definitions, you use the variable carrier without it being in scope.
When you declare the variable sub carrier in your constructor, it is only accessible in the same scope, that is, inside the constructor. Once your program leaves the scope, the variable carrier is deallocated (deleted).
You must add the variable sub carrier as a member to your class like so:
class object
{
private:
sub carrier
// other stuff
}
Edit:
I so you edited your question.
You must either replace cout with std::cout because cout is part of the c++ standard library. Alternatively, a less verbose option would be to add using namespace std; at the top of every .cpp file. This basically tells the compiler that you can use the namespace std without explicitly saying it. But don't do it for .h files. It's not a good idea.

referring to a class from another file with the scope operator (::)

I have a main.cpp file, with #include "engine.h" in the beginning.
Inside engine.h there's
#include "myObject.h"
namespace nmspc{
MyObject obj1;
//some code here
}
and myObject.h has:
#include <iostream>
class MyObject{
public:
void helloWorld(){
std::cout << "Hello, World!" << std::endl;
}
}
Why can't I refer have in my main.cpp something like this?:
int main{
nmspc::obj1::helloWorld();
return 0;
}
instead I have to type either nmspc::obj1.helloWorld(), or MyObject::helloWorld(). But I'd like to use the one above.
You can do something like this using static member functions, by adding the keyword static before the method declaration. if you do this, the function will not be associated with an actual instantiation of the class, so cannot access any member variables or non-static member functions.
In general, you wouldn't access static member functions through the created object, but through the class name (although it is possible to call it through an instance).
class MyObject{
public:
static void helloWorld() {
std::cout << "Hello, World!" << std::endl;
}
}
int main{
MyObject::helloWorld();
return 0;
}
Whether or not you should do this is dependant on the context. Your program is simple enough that's its not immediately clear why you would make it a static member function, rather than a free function, but I'm not sure I have enough context to give advice.
1st of all
incorrect header content
#include "myObject.h"
namespace nmspc{
MyObject obj1;
//some code here
}
this should be in a cpp module i.e: a translation unit
as it is an instantiation i.e. a dynamic related thing (run time affect code)
whereas header is the place for all of the static related content
if like to write MyObject::helloWorld()
may have it here
myObject.h :
#include <iostream>
namespace nmspc{
class MyObject{
public:
void helloWorld();
};
MyObject::helloWorld(){
std::cout << "Hello, World!" << std::endl;
}
}
because :: (scope resolution op.) is what name space or class/struct referred to
e.g. nmspc::MyObject::helloWorld
might be helloWorld class inside MyObject class belong to nmspc name space
might be helloWorld class belong to MyObject name space belong to nmspc name space. etc
int main{
MyObject obj1;
//some code here
nmspc::obj1.helloWorld();
return 0;
}

"Using" directives inside classes

Following my previous question. I've settled on using using directives to alias types inside my classes to avoid importing other stuff and polluting other headers that use these offending headers.
namespace MyLibrary {
namespace MyModule1 {
class MyClass1 {
public:
float X;
float Y;
MyClass1(float x, float y): X(x), Y(y) {}
};
} // namespace MyModule1
namespace MyModule2 {
class MyClass2 {
private:
// as suggested in linked question
using MyCustomType1 = MyLibrary::MyModule1::MyClass1;
public:
void DoSomething(MyCustomType1 parameter) {
std::cout << parameter.X << std::endl;
std::cout << parameter.Y << std::endl;
}
};
} // namespace MyModule2
} // namespace MyLibrary
int main(int argc, char* argv[])
{
MyLibrary::MyModule1::MyClass1 some_parameter(1.0f, 2.0f);
MyLibrary::MyModule2::MyClass2 some_var;
// Can't do this
// MyLibrary::MyModule2::MyClass2::MyCustomType1 some_other_var;
// But I can do this
some_var.DoSomething(some_parameter);
return 0;
}
How will the users outside of the MyLibrary namespace know what is MyCustomType1 if it is aliased inside a class (privately)?
Is my usage here of using legal, or is this a dirty hack I'm accidentally doing?
They will know for the simple reason you have to #include the declarations of both classes.
Having read this, and the previous question, I think the missing concept here is the concept of forward declarations.
Consider the following header file, let's called this file mymodule1_fwd.H:
namespace MyLibrary {
namespace MyModule1 {
class MyClass1;
} // namespace MyModule1
}
That's it. This is sufficient for you to declare MyClass2:
#include "mymodule1_fwd.H"
namespace MyModule2 {
class MyClass2 {
private:
// as suggested in linked question
using MyCustomType1 = MyLibrary::MyModule1::MyClass1;
public:
void DoSomething(MyCustomType1 parameter);
};
} // namespace MyModule2
Note that including this header file only will not really automatically get the entire MyModule class declaration. Also note the following:
You can't define the contents of the inline DoSomething() class method, because it actually uses the aliased type. This has the following consequences:
You have to define the DoSomething() method somewhere, in some way, probably inside the .C implementation translation module.
Similarly, you have to have declare the actual MyClass1 class from the mymodule1_fwd.H header file. I am using my own personal naming convention here, "filename_fwd.H" for forward declarations, the forward declaration header file; and "filename.H" for the actual class implementation, the implementation header file.
Callers of the DoSomething() method will have to explicitly #include the actual class declaration header file for MyClass, since they have to pass it as a parameter.
You can't really avoid the fact that the callers have to know the class that they're actually using to pass parameters. But only the callers of the DoSomething() method will need that. Something that uses other parts of the MyClass2, and don't invoke DoSomething(), don't need to know anything about MyClass1, and the actual class declaration won't be visible to them unless they explicitly #include the class implementation header file.
Now, if you still need DoSomething() to be inlined, for performance reasons, there are a couple of tricks that can be used, with preprocessor directives, that if someone #includes all the necessary header files, they'll get the inlined declaration of the DoSomething() method.
But that'll have to be another question.

Class declarations in header files

Ive been using c++ for some months now but Ive come across an error when I use header and source code files. I create a source code file
that contains a class gun(example not actual program):
class gun
{
private:
int stuff;
public:
void doStuff();
};
void Gun::doStuff()
{
cout << stuff << endl;
}
and then i created a header file and declared the class like this:
class gun;
then in my main source file i do this:
int main()
{
gun *mygun = new gun;
mygun->doStuff();
return 0;
}
however when i try to execute it i get the error:
invalid use of incomplete type 'class gun' and i think the problem is how i declared it in the header, did i do it wrong? how was i meant to do it? thanks.
Thanks Everyone that helped! I understand now, i thought that only the forward declaration
went into the header file, thanks for all your answers!
You seem to be going about seperating the implementation and header file the wrong way. Forward declarations should not go in the header file. The entire declaration should! This is how your code should be structured
Gun.hpp
#pragma once
class Gun
{
private:
int stuff;
public:
void doStuff();
};
Gun.cpp
#include "Gun.hpp"
#include <iostream>
using std::cout;
using std::endl;
void Gun::doStuff()
{
cout << stuff << endl;
}
main.cpp
int main()
{
Gun *mygun = new Gun;
mygun->doStuff();
delete mygun; // <-- remember this!
return 0;
}
the separation of header and implementation is crucial in C++ and other languages! You should only declare the class in the header along with its full interface (as above) and include all implementation details in the .cpp file (as above :)
The entire declaration of the gun class needs to be in the header file. What you declared in the header file is a forward declaration, which is not enough by itself to create an instance of the class. Forward declarations are useful for allowing other code to declare pointers only, since the compiler does not need to know the full details just to declare a pointer. But a forward declaration can't be used for creating actual object instances of the class. That is why you are getting errors about an incomplete type. From main()'s perspective, it has no idea what gun actually looks like, so it can't create a full instance of it.
The implementation of the methods for the gun class needs to be in the gun's source file, which can #include the header file to validate and access the class members.
gun.h
#ifndef gun_h
#define gun_h
class gun
{
private:
int stuff;
public:
void doStuff();
};
#endif
gun.cpp
#include "gun.h"
#include <iostream>
void gun::doStuff()
{
std::cout << stuff << std::endl;
}
Now, in main() (or any other source file), you can #include the header file and use the class as needed:
#include "gun.h"
int main()
{
gun *mygun = new gun;
mygun->doStuff();
delete mygun;
return 0;
}
In gun.h
#ifndef GUN_H_
#define GUN_H_
// You can use #pragma once too here
class gun
{
private:
int stuff;
public:
void doStuff();
};
#endif
In gun.cpp file
#include "gun.h"
void gun::doStuff()
{
cout << stuff << endl;
}
and then main.cpp
#include "gun.h"
int main() {
//your code using the class
gun *mygun = new gun;
mygun->doStuff();
return 0;
}
and you can compile and test using
g++ -o prg_name gun.cpp main.cpp && ./prg_name

template class with functions that do not use the template

I am jumping through hoops to reduce inheritance.
I read one similar question here. It shows how the issue can be resolved using a base class. I try to loose inheritance, so I am looking for something different - more along the lines of annotation.
I create and compile a template class with one specialisation (normal). The method that requires the template is in the header (Mixer.hpp). The method that does not require the template is in the cpp file (Mixer.cpp). When compiled into a static library, the cpp part only gets compiled as one specialisation (Mixer<normal>). The compiler does not know about (awsome) at that time. Importing the resulting static library into another project and attempting to create a different generic (awsome) class results in a linker error because obviously the library does not contain that method identifier (Mixer<awesome>::noTemplateInvolved). However the code for the normal implementation is as good as any so really the linker could just link to the existing source of the other template version (Mixer<?dontcare?>::noTemplateInvolved). All that the compiler has to do is to mark it appropriately for the linker.
Here is source code that results in a linker error:
//Target compiled to Provider.lib
//Mixer.hpp
#pragma once
#include <iostream>
using namespace std;
struct normal { static void log() { cout << "normal\n"; } };
template<typename output = normal>
class Mixer
{
public:
void callingTemplate();
void noTemplateInvolved();
};
template<typename output>
void Mixer<output>::callingTemplate() { output::log(); }
//Mixer.cpp
#include "Mixer.hpp"
void Mixer<>::noTemplateInvolved()
{
cout << "noTemplateInvolved\n";
}
//Target Compiled to User.exe
//This target imports Provider.lib
#include <Provider\Mixer.hpp>
#pragma comment(lib, "Provider.lib")
struct awsome { static void log() { cout << "awsome\n"; } };
int main()
{
Mixer<> n;
n.callingTemplate();
n.noTemplateInvolved();
Mixer<awsome> a;
a.callingTemplate();
a.noTemplateInvolved(); //linker error here
return 0;
}
The class Mixer<awsome> can link to the method callingTemplate because its definition is in the header and the compiler creates that function. At User.exe compile time the definition of noTemplateInvolved is hidden from the compiler. The compiler can not create that method and linking has to fail.
There are three solutions that I am aware of.
move the definition of noTemplateInvolved to the header.
include the cpp file
inherit from a baseclass
I am looking for another solution. The body of noTemplateInvolved really has nothing to do with the template. I would like to annotate the method in the header. I want the compiler to know it should always use the same base implementation regardless of the template.
Is that at all possible?
EDIT: Annotated that boring paragraph at the beginning a bit.
The answer turns out to be a base class as suggested in the comments. One of the reasons I wanted a base class is that I did not want to refactor. Refactoring using a base class is actually really simple.
Rename the original class to original_base.
Inherit from original_template inherits from original_base. Make sure to copy the contructor and pass through all the arguments to the base class.
The statement using original = original_template<your default case here> ensures that no other source code has to be modified just yet.
Applied to the example above I ended up doing something like this:
//Target compiled to Provider.lib
//Mixer.hpp
#pragma once
#include <iostream>
using namespace std;
struct normal { static void log() { cout << "normal\n"; } };
class Mixer_Base
{
private:
int mixcount;
public:
Mixer_Base(int count);
void noTemplateInvolved();
};
template<typename output = normal>
class Mixer_tempalte : public Mixer_Base
{
public:
Mixer_tempalte(int count) : Mixer_Base(count)
{}
void callingTemplate();
};
template<typename output>
void Mixer_tempalte<output>::callingTemplate()
{
output::log();
}
using Mixer = Mixer_tempalte<>;
//Mixer.cpp
#include "Mixer.hpp"
void Mixer_Base::noTemplateInvolved()
{
cout << "noTemplateInvolved\n";
}
Mixer_Base::Mixer_Base(int count) : mixcount(count)
{}
//Target Compiled to User.exe
//This target imports Provider.lib
#include <Provider\Mixer.hpp>
#pragma comment(lib, "Provider.lib")
struct awsome { static void log() { cout << "awsome\n"; } };
int main()
{
Mixer n(4);
n.callingTemplate();
n.noTemplateInvolved();
Mixer_tempalte<awsome> a(3);
a.callingTemplate();
a.noTemplateInvolved();
return 0;
}
In a way an annotation feels just like the base class feels. Everything in the base class is now annotated the way I wanted it to be, though this does not reduce inheritance.