1

I'm trying to learn how to properly create separate classes in my c++.

Every tutorial on classes have the custom class in the same file like this.

I found this question on combining different files but it doesn't deal with classes.

I've created 3 simple files to learn creating classes in different files.

car.h

#ifndef CAR_H
#define CAR_H

class Car
{
    public:
        Car();
        Car(double wieght);
        double get_wieght();
        void set_wieght(double wieght);
        ~Car();
    private:
        double wieght;
};

#ENDIF //CAR_H

car.cpp

#include "car.h"

class Car
{
    public:
        
        Car(){
            wieght = 10.0;
        }
        
        Car(double wieght){
            this->wieght = wieght;
        }

        double get_wieght(){
            return wieght;
        }
        
        void set_wieght(double wieght){
            this->wieght = wieght;
        }

        ~Car(){

        }

    private:
        double wieght;
};

main.cpp

//Program to learn how to use multiple files

#include <iostream>
#include "car.h"

using namespace std;
int main(){
    Car c;
    c.set_wieght(100.0);

    cout << "Car wiegth: " << c.get_wieght() << endl;
}

My output error when I try to compile it with g++ Main_Multiple_Files.cpp -o main.exe:

Undefined symbols for architecture x86_64:
  "Car::get_wieght()", referenced from:
      _main in Main_Multiple_Files-fbf3f8.o
  "Car::set_wieght(double)", referenced from:
      _main in Main_Multiple_Files-fbf3f8.o
  "Car::Car()", referenced from:
      _main in Main_Multiple_Files-fbf3f8.o
  "Car::~Car()", referenced from:
      _main in Main_Multiple_Files-fbf3f8.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Trying to link the files with g++ Main_Multiple_Files.cpp car.cpp -o main.exe:

In file included from Main_Multiple_Files.cpp:4:
./car.h:41:2: error: invalid preprocessing directive
#ENDIF //CAR_H
 ^
./car.h:1:2: error: unterminated conditional directive
#ifndef CAR_H
 ^
2 errors generated.
In file included from car.cpp:1:
./car.h:41:2: error: invalid preprocessing directive
#ENDIF //CAR_H
 ^
./car.h:1:2: error: unterminated conditional directive
#ifndef CAR_H
 ^
car.cpp:3:7: error: redefinition of 'Car'
class Car
      ^
./car.h:4:7: note: previous definition is here
class Car
      ^
3 errors generated.

What do I need to do to get this class working? Feel free to obliterate my code I've been trying to do this for a while now.

Funlamb
  • 551
  • 7
  • 20
  • The first error that is listed is *Undefined symbols for architecture x86_64*. Please search this site for that exact phrase, as that question has been asked and answered here many times before. When you get that issue straightened out, you can try to compile your code again to see if there are any additional issues. The **very first thing** you should do before posting here is to do a thorough search to see if it's been asked and answered here before; we expect you to make a serious effort to solve the problem yourself first, and a search is a very minimal effort which you havenot done. – Ken White Oct 02 '22 at 03:51
  • What you should do is `rm car.h` and `mv car.cpp car.h`. That will allow it to work. If you really want the function bodies to be in a separate file, then you need to use a different syntax. – Tim Roberts Oct 02 '22 at 03:51
  • If "every tutorial" you've looked at only covers classes that conveniently fit in a single header file, you might be looking at pretty low-quality material. For instance, [learncpp](https://www.learncpp.com/cpp-tutorial/class-code-and-header-files/) has a section on splitting classes across header and source files. Any textbook should cover similar territory. There's also [this question here on SO](https://stackoverflow.com/questions/9579930/separating-class-code-into-a-header-and-cpp-file) that covers the basics. – Nathan Pierson Oct 02 '22 at 05:13
  • @TimRoberts Just have everything in the `.h` file? I thought the header file was just for function function signatures and the `.cpp` file was for defining the functions. – Funlamb Oct 03 '22 at 00:49
  • @NathanPierson Thanks for the links. I've been searching for different material but everything from w3schools.com to geeksforgeeks.org/ just came up short. – Funlamb Oct 03 '22 at 00:53
  • @Funlamb -- You can do it either way. If the function bodies are small, you can put them in the .h file. If they are large, it makes compilation quicker to put them in a .cpp, so they don't have to be recompiled for every file. Have you ever looked at the standard library include files? Many of the STL files are HUGE, and almost all of the bodies are inline. – Tim Roberts Oct 03 '22 at 01:31
  • @TimRoberts I have not looked at the standard library. I'll have to deep dive into that when I have some more time. – Funlamb Oct 04 '22 at 18:35

2 Answers2

1

If you really want the bodies separate, your Car.cpp should look like this:

#include "car.h"

Car::Car(){
    wieght = 10.0;
}
        
Car::Car(double wieght){
    this->wieght = wieght;
}

double Car::get_wieght(){
    return wieght;
}
       
void Car::set_wieght(double wieght){
     this->wieght = wieght;
}

~Car::Car(){
}

(Side note: you have misspelled "weight".)

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
1

You're declaring two separate Car classes. The class Car { ... } part should only occur in the header. Then your .cpp file should contain the function bodies, using the fully qualified name of the function as the prototype. So, for the first constructor, the declaration in the header should read

class Car {
  Car();
  ...
}

whereas the version in .cpp should read

// Note: *Not* inside of 'class Car {...}'
Car::Car(){
  wieght = 10.0;
}

Then, similarly, for member functions that have bodies,

void Car::set_weight(double weight) {
  this->weight = weight;
}
Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116