I’ve been programming in C# for a few years now, as it was my first language. I’m trying to brush up on my c++ because I will be working on something soon that is coded in that.
What is wrong with this code: (I know there might be a lot of things wrong. C++ is so different than C# in what it needs). Someone told me that I don’t know how to declare classes correctly in C++, and that I need to define my classes using headers. Do I NEED headers? This is a small program just to test and would like to know if this can be accomplished without it. And are the missing headers the only issue here? I had a error about not being able to access Parse in Company, but when I add public in front of Company class name, it throws more errors.
AUGH! So frustrating.
#include "std_lib_facilities.h"
using namespace std;
class Employee
{
public:
string screen_name;
string real_name;
string current_job;
int employee_number;
Employee(int no, string name1, string name2, string current_jobin)
{
screen_name=name1;
real_name=name2;
employee_number=no;
current_job=current_jobin;
}
};
class Project
{
public:
Vector<Employee> Employees;
int max_worker_quota;
int project_id;
string project_name;
Project(int no_in,int max_in,string title_in)
{
max_worker_quota=max_in;
project_name=title_in;
project_id=no_in;
}
};
unsigned int split(const std::string &txt, vector<std::string> &strs, char ch)
{
unsigned int pos = txt.find( ch );
unsigned int initialPos = 0;
strs.clear();
// Decompose statement
while( pos != std::string::npos ) {
strs.push_back( txt.substr( initialPos, pos - initialPos + 1 ) );
initialPos = pos + 1;
pos = txt.find( ch, initialPos );
}
// Add the last one
strs.push_back( txt.substr( initialPos, std::min( pos, txt.size() ) - initialPos + 1));
return strs.size();
}
class Company
{
Vector<Employee> Employeelist;
Vector<Project> Projectlist;
void Parse(string input)
{
//Case Statements
vector<string> temp;
split( input, temp, ' ' );
if (temp[0]=="S")
{
//Add Employee to Company
Employee myEmployee=Employee(atoi(temp[1].c_str()),temp[2],temp[3],temp[4]);
Employeelist.push_back(myEmployee);
}
else if (temp[0]=="C")
{
//Add Project to Company
Project myProject=Project(atoi(temp[1].c_str()),atoi(temp[2].c_str()),temp[3]);
Projectlist.push_back(myProject);
}
else if (temp[0]=="L")
{
//Add Employee to Project list
//Not Implemented-Find Project by temp[1] which is a int
}
else if (temp[0]=="A")
{
}
else if (temp[0]=="D")
{
}
else if (temp[0]=="PS")
{
}
else if (temp[0]=="PC")
{
}
}
};
int main(int argc, char *argv[])
{
string input;
cout<<"Command:: ";
cin>>input;
Company myCompany;
myCompany.Parse(input); //Input is in the format X Name Name etc etc. Arguments separated by spaces
return 0;
}
First of all, you don’t need headers for test purposes. But you can not make a real program without them, because the headers define the interface of separately compiled program parts. That’s the way the C/C++ work, no way around.
Second, you have to add
public:to yourCompanyclass and deal with the following errors. It is just like the C# stuff: you have to make a function definedpublic void Parse(string)to be able to access it from outside the class. The C++ way isThird, it is unconventional in C++ to define non-trivial functions inside class definition (the only exception being template classes). That’s the other side of the headers story tho.
OK, here is a brief explanation of basic header-related stuff.
Program is usually divided into the set of separately compiled files, that is to say translation units. Each unit usually consist of one
.cppfile and one or more header files (.h). When these files are compiled you are getting a single binary .obj file. This file contains objects – the code for your functions and stuff needed to initialize global (and namespace) objects. To make a program you need to pass one or more object files to linker. In VS it happens behind the scene. You just add a .cpp file to your project tree and IDE will configure the project dependencies accordingly.This is how your code may look like:
So, basically we gonna have employee, company and main units. The definition of Employee class in
employee.hcontains non-trivial functions declaration. A simple function likeGetSalary()is defined right inside the class. It gives a hint to the compiler to inline it. Theemployee.cppcontains the rest of function definitions;The
company.hfile has#include "employee.h"preprocessor statement. So we may use Employee objects in the class definition and in its implementation file (company.cpp).The
main.cppcontains the program entry point. It is able to use Company class cause it includes “company.h”.If we change something in the Employee::Hire() function implementation, only
employee.objwill be recompiled. This is the main purpose of such program organization. But if we change the Employee interface (class definition inemployee.h) every program unit will require recompilation.Include guards are needed in case you do something like this:
Projects based on Microsoft Visual C++ often use
#pragma oncefor the same purpose. It is easier to use but generally not portable.If you put, for example, Employee::Hire definition in the
employee.hthe compiler will put the function code in both employee.obj and company.obj (cause thecompany.hincludesemployee.h). When you try to link in such situation the linker will encounter 2 versions of the same function code and will give an error. Inline functions are not compiled in into separate entities and thus don’t cause such error. Same goes about template code which is generated only when the template is instantiated. So, several translation units may have code for the same non-inline template functions.It is up to programmer to define the parts boundaries of the program. You may put Company and Employee into single translation unit, if you want. The VS wizards tend to make a .h/.cpp pair for each major class tho. Try to make an MFC project and see for yourself.
These are the basics. As I mentioned in the comment above, you can get a full picture of such stuff from Stroustrup’s “The C++ programming language”