I have created a small c++ application with a header file, a cpp file, and a main function.
I expected that the header file would be an interface, that would just define my functions and properties, but the cpp file would be the one to implement.
However when I create my files, in my main function I have a breakpoint and try to step into my method, it just takes me straight to the header file definition instead of the implementing cpp file. Here is my code:
//header file
#pragma once
#include <string>
#include <SQLAPI.h>
class DbConnection
{
public:
int Id, Age;
std::string Name;
void ConnectToDatabase(const std::string databaseName) { }
void Retrieve(const std::string table) { }
};
Here is my cpp file:
#include "DbConnection.h"
#include <string>
#include <SQLAPI.h>
#include <iostream>
SAConnection sqlCon;
SACommand sqlCmd(&sqlCon);
int Id, Age;
std::string Name;
void ConnectToDatabase(const std::string databaseName)
{
sqlCon.Connect(
databaseName,
",
",
SA_SQLServer_Client);
}
void Retrieve(const std::string table)
{
//code to retrieve data
std::cout << "success";
}
My main function which is in a separate cpp file. I set a breakpoint and attempt to step into the method Retrieve and it takes me to the header file instead of the cpp. Any help with debugging is appreciated.
#include "DbConnection.h"
#include <stdio.h>
#include <iostream>
int main()
{
DbConnection con;
con.ConnectToDatabase(
"databaseParameter");
con.Retrieve("tableParameter");
return 0;
}
I assume it is one of two things, either my debugger in visual studio 2019 is not set to the proper setting, or it has to do with how my #include "DbConnection.h" statements are included in both cpp files.
Two things:
You have to write in the cpp file
void DbConnection::ConnectToDatabase(const std::string databaseName)
{
...
}
and so for the Retrieve function to tell the compiler that this is the function of the class.
You actually implemented the function in the header file when you put {} after the function declaration.
Related
I'm able to build and run a particular project in Visual Studio when all of the code is in one main .cpp file, but when I separate the file into a class (.cpp and .h) and main .cpp file, I get several weird errors.
Here is the code when it's in 3 separate files, and not working:
//main.cpp
#include "student.h"
#include <string>
#include <iostream>
using namespace std;
int main()
{
std::cout << "Hello World!\n";
Student student;
student.setStudentID("A1C");
student.print();
}
//Student.h
#ifndef STUDENT_H
#define STUDENT_H
class Student
{
public:
Student();
string getStudentID() const;
void setStudentID(string studentID);
void print();
private:
string studentID;
};
#endif
//Student.cpp
#include "Student.h"
#include <string>
#include <iostream>
using namespace std;
Student::Student() {
this->studentID = "default";
}
string Student::getStudentID() const {
return this->studentID;
}
void Student::setStudentID(string studentID) {
this->studentID = studentID;
}
void Student::print() {
cout << "student ID: " << studentID << endl;
}
Here is the code when it's all in one main.cpp file, and working:
#include <string>
#include <iostream>
using namespace std;
class Student
{
public:
Student();
string getStudentID(); //const?
void setStudentID(string studentID);
void print();
private:
string studentID;
};
int main()
{
std::cout << "Hello World!\n";
Student student;
student.setStudentID("A1C");
student.print();
}
Student::Student() {
this->studentID = "default";
}
string Student::getStudentID() { //const?
return this->studentID;
}
void Student::setStudentID(string studentID) {
this->studentID = studentID;
}
void Student::print() {
cout << "student ID: " << studentID << endl;
}
Here are some of the errors that I get:
In the file Student.h you are using string, but string is not (yet) known. Read the Include file from top to bottom. Nowhere in the file is there any hint as to what string is supposed to be.
#include <string> in your Student.h file will introduce std::string to the file. From here on, std::string will be valid. But that's still not enough, since you are using string and not std::string in your class.
Do not include a using namespace std in your header file. If you do so, you force this namespace on all your "customers" of the header file. If any other file includes your Student.h with the using namespace in it, they will also get the using namespace... statement, even if they do not want it. Headerfiles should be self contained and should not introduce stuff, others may not want.
Also do not add a using std::string in your header file. While not as bad as a using namespace std there may be (and later in your professional life will be) instances, where you have different kinds of string. Perhaps a std::string and an oldfashioned::string or utf_something::string.
For simplicity, just write std::string studentId. IOW, use the fully qualified name of string in your header file.
In .cpp files these rules are somewhat relaxed, since no other file will include your .cpp file.
Bonus:
lookup #pragma once
always include system headers before your own headers
But beware of include order. Every header file should include all headers it needs, because ...
... the worst thing that can happen is that your code changes depending on the order in which you include headers. It should not matter. Including "Student.h" should introduce the Student class and nothing else.
Bonus++
take your time to learn about the C(++) preprocessor. #include is not really a C++ language statement like class, for etc... It is just a directive for the compiler to read the included file first.
Your compiler will have a switch (such as /P with Microsoft Visual C++) which will not compile the code but produce the actual included files and store the in a *.p (or something) file. It will let you see what the preprocessor does with your code before it is passed on to the compiler. It's an interesting and teaching experience. Try it. Don't be put off by the seemingly complex file. Search for "class Student" in that file and take it from there.
change student.h to this
//Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
class Student
{
public:
Student();
std::string getStudentID() const;
void setStudentID(std::string studentID);
void print();
private:
std::string studentID;
};
#endif
and it compiles and runs fine
BTW.
dont do this
void Student::setStudentID(string studentID) {
this->studentID = studentID;
}
have a naming convention for fields in a class so they are distinct
ie
//Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
class Student
{
public:
Student();
std::string getStudentID() const;
void setStudentID(std::string studentID);
void print();
private:
std::string studentID_; <<<<========
};
then
void Student::setStudentID(string studentID) {
studentID_ = studentID;
}
why, because
First its the accepted way in c++ world (the naming standard might differ, m_ prefix is common too)
second you might write this
void Student::setStudentID(string studentID) {
studentID = studentID;
}
which will compile but is maybe not what you mean. Of course here its obvious but in denser code, not so much
In one of my modules, I have a function (changeNum) that returns a string and accepts a parameter that is a string. I tried to declare this function in my header file as following:
std::string changeNum(std::string s);
[and I included the string header file into the header file as well]
but I'm still getting the following error in my header file: "unknown type name 'string'" What do I do?
Here is the whole code:
My header file is the following:
#pragma once
#include <string>
std::string changeNum(std::string s);
My module with the function changeNum is defined as the following
#include <string>
string changeNum(string s){
return s;
}
Try it:
Header.h
#pragma once
#include <string>
std::string changeNum(std::string s);
Source.cpp
#include "Header.h"
std::string changeNum(std::string s) {
return s;
}
main.cpp
#include "Header.h"
#include <iostream>
int main()
{
std::string sample_str = changeNum("Hello");
std::cout << sample_str.c_str();
}
Tested on VS and removed #include "pch.h" from aforementioned code.
I just started learning how to write C++ code using CLion but I am running into some issues using classes. To my understanding, functions and methods are declared in the .h file and then they can be used in the .cpp file. If I do it this way then I get the error message "Can't resolve variable studentName". The message goes away if I declare the variable in the .cpp file but then doesn't that defeat the purpose of the .h file? Thank you in advance to whoever can help me resolve this issue.
Student.h
#ifndef PRACTICE_STUDENT_H
#define PRACTICE_STUDENT_H
#include <string>
class Student {
std:: string studentName;
int gradeLevel;
Student :: Student(std:: string studentName, int gradeLevel);
std:: string getName();
};
#endif //PRACTICE_STUDENT_H
Student.cpp
#include "Student.h"
#include <string>
Student:: Student(std:: string i_studentName, int i_gradeLevel){
gradeLevel = i_gradeLevel;
}
std:: string getName() {
return studentName;
}
main.cpp
#include <iostream>
#include "Student.h"
using namespace std;
int main(){
Student Carlton = Carlton.("Carlton", 16);
cout << Carlton.getName();
return 0;
}
getName is a member function of the Student class. To implement it in your .cpp file, you need to properly indicate that it belongs to that class:
std::string Student::getName() {
return studentName;
}
I am taking a C++ class, and for some reason I can't get the classes in my header file to work on one of my programs. I am using Visual Studio 2017, and I added both my header file and my implementation file together with my test file by using the Solution Explorer in Visual Studio.
I have two constructors in my program, one default and one not. I tried deleting the second one from each file, and the program ran, but I can't get it to work otherwise.
Header File:
#pragma once
class BuckysClass {
public:
BuckysClass();
BuckysClass(string);
void coolSaying();
};
Implementation File:
#include "stdafx.h"
#include <iostream>
#include "BuckysClass.h"
#include <string>
using namespace std;
BuckysClass::BuckysClass() {
cout << "Bucky is ";
}
BuckysClass::BuckysClass(string x) {
cout << x;
}
void BuckysClass::coolSaying() {
cout << "preachin to the choir" << endl;
}
Test File:
#include "stdafx.h"
#include <iostream>
#include <string>
#include "BuckysClass.h"
using namespace std;
int main() {
BuckysClass buckysObject;
buckysObject.coolSaying();
BuckysClass buckysObject2("Bucky is not ");
buckysObject2.coolSaying();
system("Pause");
return 0;
}
syntax error:identifier 'string'
#include <string>//include the string header
class BuckysClass {
public:
BuckysClass();
BuckysClass(std::string);//add the namespace identifier
void coolSaying();
};
Your header file BuckysClass.h does not have the <string> Header file included.
Add:
#include<string>
using namespace std;
you should remove these includes from the corresponding .cpp file and just keep BuckysClass.h in cpp files.
Here are some more pictures of the test file and the error message I got that I couldn't post above.
Test File
Error Messages
I am creating a function to read the contents of a file, located in an IO.cpp file:
#include "IO.h"
#include <iostream>
#include <fstream>
IO::IO()
{
//ctor
}
void IO::readFile(std::string fileName)
{
std::ofstream inputFile;
inputFile.open(FileName);
inputFile >> fileName.toStdString;
inputFile.close();
std::cout << fileName;
}
With the header file IO.h:
#ifndef IO_H
#define IO_H
class IO
{
public:
IO();
void readFile(std::string inputFile);
protected:
private:
};
#endif // IO_H
But I get an error from Clang that says
include/IO.h|9|error: use of undeclared identifier 'std'|
And I can't figure out how to solve it.
When parsing the header (specifically the void readFile(std::string inputFile); line), the compiler doesn't know an std namespace exists, much less string exists inside that namespace.
#include <string> in the header.
In many cases this occurs when you forget to include #include <iostream> on implementation of methods on a separate file i.e. outside main function (i.e. when you go header file route)