I always arranged my C++ headers and source files this way:
prog.h
#include <iostream>
class Prog
{
public:
Prog(std::string);
~Prog();
void printName();
private:
std::string name;
};
#include "prog.cpp"
prog.cpp
Prog::Prog(std::string n):
name(n)
{
std::cout << "Program \"" << name << "\" started.\n";
}
Prog::~Prog()
{
std::cout << "Program \"" << name << "\" ended.\n";
}
void Prog::printName()
{
std::cout << "Program name is: \"" << name << "\".\n";
}
main.cpp
#include "prog.h"
int main()
{
Prog prog {"MyCalculator"};
prog.printName();
return 0;
}
But I recently discovered that it's common to arrange them this other way:
prog.h
class Prog
{
public:
Prog(std::string);
~Prog();
void printName();
private:
std::string name;
};
prog.cpp
#include <iostream>
#include "prog.h"
Prog::Prog(std::string n):
name(n)
{
std::cout << "Program \"" << name << "\" started.\n";
}
Prog::~Prog()
{
std::cout << "Program \"" << name << "\" ended.\n";
}
void Prog::printName()
{
std::cout << "Program name is: \"" << name << "\".\n";
}
main.cpp
#include <iostream>
#include "prog.h"
int main()
{
Prog prog {"MyCalculator"};
prog.printName();
return 0;
}
I find the first method more convenient, so is there any reason why I should prefer the second method over the first one?
Header files shouldn't include source code.
I think the first method could provoke dependency errors in a complex enough project (for example, using circular dependencies), because don't separate declaration and definition.
The compilation time is faster in the second one, because you can compile each source file separately.
Also, you might find this question useful.
The first version is what the book "Accelerated C++" (ed. 2000) suggests to do when first introducing header files for class declarations.
I suppose the second version can be seen as more elegant because it groups together all #include pre-compiler statements at the beginning of the program.
Related
I've created a minimal example to share a variable between classes.
In C# normally I do this by creating a public static class with a public static variable... then I can just access it from everywhere.
Main.cpp
#include <iostream>
#include "TestClass.h"
#include "Shared.h"
int main(int argc, char* argv[])
{
std::cout << "This should print 'Hello'" << std::endl;
std::cout << "Print 1 from main: " << MyNameSpace::MESSAGE << std::endl;
std::cout << "This should print 'Test message 1'" << std::endl;
TestClass test("Test message 1");
std::cout << "Print 2 from main: " << MyNameSpace::MESSAGE << std::endl;
std::cout << "This should print 'Test message 2'" << std::endl;
MyNameSpace::MESSAGE = "Test message 2";
std::cout << "Print 3 from main: " << MyNameSpace::MESSAGE << std::endl;
return 0;
}
Shared.h
#pragma once
#include <string>
namespace MyNameSpace
{
static std::string MESSAGE = "Hello";
}
TestClass.h
#pragma once
#include <string>
#include "Shared.h"
#include <iostream>
class TestClass {
public:
TestClass(const std::string& message);
};
TestClass.cpp
#include "TestClass.h"
TestClass::TestClass(const std::string& message)
{
MyNameSpace::MESSAGE = message;
std::cout << "Print 1 from TestClass: " << MyNameSpace::MESSAGE << std::endl;
}
So, if I set any value, for example MyNameSpace::MESSAGE = "Potato" from any file/class, I want to see Potato in MyNameSpace::MESSAGE from all classes
Here is the output so you can see better:
C:\Users\Adrian\RiderProjects\Test\x64\Debug\Test.exe
Hello:
Print 1 from main: Hello
This should print Test message 1:
Print 1 from TestClass: Test message 1
Print 2 from main: Hello
Test message 2:
Print 3 from main: Test message 2
Process finished with exit code 0.
Note that in C++ you can define public static variables in classes, and they will pretty much do what you want.
That said, use of namespaces here is almost irrelevant. It essentially means that there's a :: in the name of your variable (MyNamespace::MESSAGE), but you could alternatively call your variable MyNamespace_MESSAGE, for example.
So the question, independent of namespaces, is how can you have a global variable in C++. One way do to this is to declare the variable in a header file, and define it in a single C++ file. For example:
// message.h
extern std::string message;
// message.cc
std::string message {"Hello"};
(Wrap these in a namespace if you want.) Alternatively, if you just want to put it in a header file, use:
// header.h
inline std::string message{"Hello"};
Outside of a class, static just means static linkage, meaning that you can't access the variable from other translation units. That's not what you want.
I am doing my c ++ homework and am having difficulty in one little thing
Here is the text:
Create program in C++ in OOP structure, splitting it at least into 3 files. The class header should be put in header file (program.h). All the methods should be implemented outside the header – in a special C++ file (program.cpp). Function main should be put in yet another C++ file (main.cpp). By default, all class fields are private, but class methods - public. Unlike previous programs, it is not required to follow specific interface rules.
Create class "Date" with three numbers stored - year, month, day. The following class methods should be created: (1) a constructor to initialize an object with given initial values, (2) destructor which should notify about deleting the object, (3) method "change" with 3 parameters, (4) method "day" – which calculates and prints the weekday of date, (5) method "print", which prints the date.
I created 3 files main.cpp program.h programm.cpp
main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "program.h"
using namespace std;
int main() {
Date s= Date(2002, 02, 18);
s.print();
s.change(1996, 02, 18);
s.print();
s.day();
return 0;
}
program.h
#ifndef ADD_H
#define ADD_H
#include <iostream>
#include <string>
struct Date {
public:
Date() {
year = 0;
month = 0;
dayc = 0;
}
//counstructor
Date(int n_year, int n_month, int n_day) {
year = n_year;
month = n_month;
dayc = n_day;
}
//destructor
~Date() {
std::cout << "Destructor deleted Date " << year << " " << month << " " << dayc << " " << std::endl;
}
void change(int c_year, int c_month, int c_day) {
year = c_year;
month = c_month;
dayc = c_day;
}
void day() {
//LONG CODE WITH CALCULATION
}
void print() {
std::cout << "Date is " << dayc << " " << month << " " << year << " " << std::endl;
}
private:
int year;
int month;
int dayc;
};
#endif
and empty programm.cpp
I need to do the OOP part and separate code to 3 files
The homework assignment tells you to separate code from the header. To do this you need to leave only declarations in the header like so:
Program.h:
#include <iostream>
class Date {
public:
Date(int, int, int);
void day();
private:
int _year;
int _month;
int _day;
};
Program.cpp:
#include "Program.h"
Date::Date(int year, int month, int day):
_year(year),
_month(month),
_day(day)
{
// only code should go here, not initializations
std::cout << "Constructor called" << std::endl;
}
void Date::day()
{
// your calculation
}
Your question suggests you haven't used more translation units yet, so you have to compile the Program.cpp first without linking (check your compiler manual), probably something like
c++ -o program.o -c program.cpp
and then compile + link the executable
c++ main.cpp program.o && ./a.out
I am trying to build plugins in c++ using boost library. helper.h
Header file:
#include <string>
#ifndef HELPER_H
#define HELPER_H
class Helper
{
public:
std::string s;
void helper_new(std::string a);
};
#endif
I defined the member function in a file helper.cpp
#include "helper.h"
namespace boostfs = boost::filesystem;
namespace boostdll = boost::dll;
namespace dll = boost::dll;
// Member Functions()
void Helper::helper_new(std::string a)
{
//int i=0;
std::cout<<"Inside helper_new function!!";
std::cout<<"\n";
std::cout<<a;
std::cout<<"\n";
/*std::ofstream MyFile("/home/deepansh/Desktop/Plugin_example/outputs/helper.txt");
std::cout << "Writing in helper.txt\n"; */
/*for(i=0;i<LONG_MAX;i++)
for(int j=0;j<LONG_MAX;j++);*/
/*MyFile<<a+" ";
MyFile<<i;
MyFile<<"\n";
MyFile.close();*/
std::cout << "Done\n";
}
int main() {
Helper obj;
std::string a;
std::cout<<"Enter string u want to write?";
std::getline(std::cin, a);
obj.s=a;
int choice=1;
std::cout<<"which strat to use? \'1\' or \'2\' ?(default is 1)";
std::cin>>choice;
std::string file="strat"+std::to_string(choice);
boostfs::path lib_path = boostfs::current_path();
boost::filesystem::path p2(std::string(lib_path.string()).append("/plugins/").append(file).append(".so"));
boost::shared_ptr<plugin_api> plugin; // variable to hold a pointer to plugin variable
std::cout << "Loading the plugin" << std::endl;
plugin = dll::import<plugin_api>( // type of imported symbol is located between `<` and `>`
p2, // path to the library and library name
"plugin", // name of the symbol to import
dll::load_mode::append_decorations // makes `libmy_plugin_sum.so` or `my_plugin_sum.dll` from `my_plugin_sum`
);
plugin->handle_task(obj);
std::cout << plugin->print() << std::endl;
}
I called the member function from another file with the help of object of Helper class passed to it as argument(this is compiles as so file) strat1.cpp
#include "../helper.h"
#include <string>
namespace my_namespace {
class strat : public plugin_api {
public:
strat() {
std::cout << "Constructing start" << std::endl;
}
std::string print() const {
return "Hello from strat 1";
}
int handle_task(Helper a) {
//long i=0;
//std::ofstream fout;
//fout.open("/home/deepansh/Desktop/Plugin_example/outputs/strat1.txt");
std::cout<<"Inside strat 1";
std::cout<<"\n";
/*for(i=0;i<LONG_MAX;i++)
for(int j=0;j<LONG_MAX;j++);*/
//fout<<a.s+" ";
//fout<<i;
//fout<<"\n";
//fout.close();
std::cout<<a.s;
std::cout<<"\n";
std::cout<<"going to the helper class function.";
std::string p="Hello man. What's up?";
a.helper_new(p); //error is here
return 0;
}
~strat() {
std::cout << "Destructing strat ;o)" << std::endl;
}
};
I am getting this error ./a.out: symbol lookup error: /home/deepansh/Desktop/Plugin_example/plugins/strat1.so: undefined symbol: _ZN6Helper10helper_newENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
When compiling the code can someone help. compiling:
Convert the plugin library(plugin implementation) to object file by using:
gcc -c -Wall -Werror -fpic strat1.c ../helper.cpp //here -wall and -Werror are for warnings
Then convert the .o files to .so files using(creating shared library from object file) :
gcc -shared -o strat1.so strat1.o
g++-8 helper.cpp -L/usr/lib/x86_64-linux-gnu -lboost_filesystem -L/usr/lib/x86_64-linux-gnu -lboost_system -ldl
when I run the executable a.out the error occurs
I'm learning C++, and I'm just messing around with putting classes in separate files for practice. I have a getter function, which returns a string (because the variable is saved as a string). However, from my main() function, I am not sure how to call it. I know the problem is probably that I need to include string somewhere when I call the object, but I have no idea how to format it.
I know this is a pretty newbie questions, but I couldn't find the answer anywhere. Could someone help me out?
(p.s. I'm not trying to get this specific code to work, since it's useless. I'm just trying to learn how to apply it for future reference).
I've tried throwing in string in a couple of places when calling or creating the object, but I always get an error. I know I could get around it by not encapsulating the variable or not having a separate class file, but that's not what I want.
main.cpp
#include <iostream>
#include "usernameclass.h"
#include <string>
using namespace std;
int main()
{
usernameclass usernameobject;
usernameobject.getUsername();
return 0;
}
usernameclass.h
#ifndef USERNAMECLASS_H
#define USERNAMECLASS_H
#include <string>
class usernameclass
{
public:
usernameclass();
std::string getUsername();
void setUsername(std::string name);
askUsername();
private:
std::string usernameVar = "test";
};
#endif
usernameclass.cpp
#include "usernameclass.h"
#include <iostream>
#include "username.h"
#include <string>
using namespace std;
string usernameclass::getUsername(){
return usernameVar;
cout << "test cout" << endl;
}
usernameclass::askUsername(){
string name;
cout << "What is your name?" << endl;
cin >> name;
setUsername(name);
cout << "Ah, so your name is "+usernameVar+", great name I guess!" << endl;
cin.get();
cin.get();
cout << "You're about to do some stuff, so get ready!" << endl;
}
usernameclass::usernameclass(){}
void usernameclass::setUsername(string name){
string* nameptr = &usernameVar;
*nameptr = name;
}
Expected result: runs getUsername() function and returns usernameVar
Actual result: doesn't run the getUsername() function
The current code would not compile, because you have not specified return type of 'askUsername()' routine, which is 'void', I believe.
Other things are good, apart from an output in 'getUsername()', which happens after returning from the function and about which you should have received a warning, I guess.
To the question: you can call that 'get' method in 'main()' as:
cout << usernameobject.getUsername();
Your code should be structured more like this instead:
main.cpp
#include <iostream>
#include "usernameclass.h"
int main()
{
usernameclass usernameobject;
// optional:
// usernameobject.askUsername();
// do something with usernameobject.getUsername() as needed...
return 0;
}
usernameclass.h
#ifndef USERNAMECLASS_H
#define USERNAMECLASS_H
#include <string>
class usernameclass
{
public:
std::string getUsername() const;
void setUsername(std::string name);
void askUsername();
private:
std::string usernameVar = "test";
};
#endif
usernameclass.cpp
#include <iostream>
#include "usernameclass.h"
std::string usernameclass::getUsername() const {
return usernameVar;
}
void usernameclass::setUsername(std::string name) {
usernameVar = name;
}
void usernameclass::askUsername() {
std::string name;
std::cout << "What is your name?" << std::endl;
std::getline(std::cin, std::name);
setUsername(name);
std::cout << "Ah, so your name is " << getUsername() << ", great name I guess!" << std::endl;
std::cout << "You're about to do some stuff, so get ready!" << std::endl;
}
I have copied this out of a book. I'm just not sure what to add in the main.cpp source file to make it run though.
I know that class declarations go in the .h file and implementations go in the .cpp file. What would I need to write in main.cpp?
I've tried lots of different things but I'm just getting so many error messages.
// cat.h
#ifndef ____2_cat_implementation__Cat__
#define ____2_cat_implementation__Cat__
#include <iostream>
using namespace std;
class Cat
{
public:
Cat (int initialAge);
~Cat();
int GetAge() { return itsAge;}
void SetAge (int age) { itsAge = age;}
void Meow() { cout << "Meow.\n";}
private: int itsAge;
};
#endif /* defined(____2_cat_implementation__Cat__) */
...
// cat.cpp
#include <iostream>
#include "Cat.h"
using namespace std;
Cat::Cat(int initialAge)
{
itsAge = initialAge;
}
Cat::~Cat()
{
}
int main()
{
Cat Frisky(5);
Frisky.Meow();
cout << "Frisky is a cat who is ";
cout << Frisky.GetAge() << " years old.\n";
Frisky.Meow();
Frisky.SetAge(7);
cout << "Now Frisky is " ;
cout << Frisky.GetAge() << " years old.\n";
return 0;
}
Look at this part again:
Cat::Cat(int initialAge);
{
itsAge = initialAge;
Cat::~Cat()
You're missing the closing } for the constructor, as well as an extra ; after the function header.
On an unrelated note, don't use global names starting with underscore (like ____2_cat_implementation__Cat__), those names a reserved by the specification.
You have a missing } and unneccessary ;
//----------------------v
Cat::Cat(int initialAge);
{
itsAge = initialAge;
}
//^
What would I need to write in main.cpp
Usially, as you have pointed out, the .h file contains the declarations and the .cpp file - the definitions. Then, the main.cpp file should contain the main function (it's not necessary to name the file, containing the main function main.cpp. It could be anything.
So, in your example, you can create a main.cpp file with the following content:
// include the declarations file
#include "cat.h"
// include the header for cin/cout/etc
#include <iostream>
using namespace std;
int main()
{
Cat Frisky(5);
Frisky.Meow();
cout << "Frisky is a cat who is ";
cout << Frisky.GetAge() << " years old.\n";
Frisky.Meow();
Frisky.SetAge(7);
cout << "Now Frisky is " ;
cout << Frisky.GetAge() << " years old.\n";
return 0;
}
Other notes:
using namespace std; is bad practice, especially in header files. Use std:: instead (for example, std::cout, std::cin, std::string, etc)
as you have .h and .cpp files, don't put half of the implementation in the header and the rest - in the source file. Put all definitions inside the source files (unless you want to inline the functions, implemented in the header)
avoid using names, starting with __ or _ - they are reserved by the standard.