1

To start off with, I'll mention I come mainly from a Java background. I do have exposure with C and understand most concepts behind C++. I'm trying to help myself learn more about the language and can't seem to figure out headers. I understand why to use them in addition to cpp files and all of that. My problem is trying to actually manage working with them. For example, defining a Vector3 header with private float variables and then overload operating. My problem comes in when I attempt to define the constructor and methods in the cpp file. I can't seem to figure out how to get access to the private variables without specifically defining the functions and the constructor in the header, which more or less leads me to believe I don't need both a header and cpp file in this instance.

Here's how I've defined the header file currently (which works, but isn't undefined as it should be):

#pragma once

#ifndef __Vector_3_H__
#define __Vector_3_H__

namespace VectorMath {

class Vector3 {

public:

    Vector3(float x, float y, float z) {
        this->x = x;
        this->y = y;
        this->z = z;
    }

    Vector3 operator+(Vector3 vector) {
        return Vector3(x + vector.x, y + vector.y, z + vector.z);
    }

    Vector3 operator-(Vector3 vector) {
        return Vector3(x - vector.x, y - vector.y, z - vector.z);
    }

    Vector3 operator*(Vector3 vector) {
        return Vector3(x * vector.x, y * vector.y, z * vector.z);
    }

    Vector3 operator/(Vector3 vector) {
        return Vector3(x / vector.x, y / vector.y, z / vector.z);
    }

    float getX() {
        return x;
    }

    float getY() {
        return y;
    }

    float getZ() {
        return z;
    }

private:

    float x;
    float y;
    float z;

};
}

#endif
Jacob
  • 91
  • 1
  • 9
  • 3
    [Don't use double underscore](http://stackoverflow.com/q/224397/10077). – Fred Larson Mar 09 '16 at 22:36
  • And especially don't use double underscore. And especially don't use double underscore followed by a capital letter. If you do UB would really get real. – user3528438 Mar 09 '16 at 22:38
  • And to answer your question: include the header in the cpp. – user3528438 Mar 09 '16 at 22:39
  • Can you show an example of a .cpp file where the definitions don't compile? It could be that you're forgetting to #include the header, or you may be forgetting the class name on the member function definition. – Fred Larson Mar 09 '16 at 22:40
  • Noted about the double underscore. My professor used it in his style, so I presumed it was correct. – Jacob Mar 09 '16 at 22:51

3 Answers3

3

It needs to look more like this instead:

Vector_3.h:

#ifndef Vector_3_H
#define Vector_3_H

#pragma once

namespace VectorMath {

class Vector3 {

public:

    Vector3(float x, float y, float z);

    Vector3 operator+(Vector3 vector);    
    Vector3 operator-(Vector3 vector);
    Vector3 operator*(Vector3 vector);
    Vector3 operator/(Vector3 vector);

    float getX();
    float getY();
    float getZ();

private:

    float x;
    float y;
    float z;

};

}

#endif

Vector_3.cpp:

#include "Vector_3.h"

namespace VectorMath {

Vector3::Vector3(float x, float y, float z) {
    this->x = x;
    this->y = y;
    this->z = z;
}

Vector3 Vector3::operator+(Vector3 vector) {
    return Vector3(x + vector.x, y + vector.y, z + vector.z);
}

Vector3 Vector3::operator-(Vector3 vector) {
    return Vector3(x - vector.x, y - vector.y, z - vector.z);
}

Vector3 Vector3::operator*(Vector3 vector) {
    return Vector3(x * vector.x, y * vector.y, z * vector.z);
}

Vector3 Vector3::operator/(Vector3 vector) {
    return Vector3(x / vector.x, y / vector.y, z / vector.z);
}

float Vector3::getX() {
    return x;
}

float Vector3::getY() {
    return y;
}

float Vector3::getZ() {
    return z;
}

}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • This works and makes sense. It appears I hadn't specified the cpp file to use the namespace VectorMath and I had also labeled it as a class. Do you not need to label the cpp file as a class because it has a header? If you do, I'm assuming you can strip out the Vector3:: part since it dictates which method in which class to define. If not, I suppose you always have to define the class prior to the method name? – Jacob Mar 09 '16 at 22:51
  • An `#include` statement is nothing more than a text replacement, the preprocessor replaces it with the content of the file that it refers to. So ultimately, the compiler only sees one big block of code - declarations followed by implementations. You have to specify the `Vector3::` when a method declaration is separated from its implementation so they can be matched up. Whether you do that in a `.cpp` file, or even in the same `.h` file, it is all the same to the compiler. If you implement the method bodies inline inside their declarations, you don't specify the `Vector3::`. – Remy Lebeau Mar 09 '16 at 23:13
  • Awesome. Thank you very much! – Jacob Mar 09 '16 at 23:18
0

If you want to use a cpp file for your constructor you should write

// File Vector3.cpp
#include "Vector3.h"

namespace VectorMath {

    Vector3::Vector3 (float x, float y, float z)         
    { 
        this->x=x;
       //...
    }

The addition should be implemented as follows if you keep it in the same namespace

    Vector3 Vector3::operator+(const Vector3& v)
    { 
        return Vector3 (x+v.x,y+v.y,z+v.z);
    }
}
Camleon
  • 113
  • 9
  • 2
    I'd use `namespace VectorMath` around my function definitions rather than specifying it for each one. Also, prefer initializers in constructors rather than assigning in the body. – Fred Larson Mar 09 '16 at 22:43
0

If you want to move the implementations of member functions away from the header file, you still need to declare them in the definition of the class. For example:

// Vector1.h
#pragma once
#ifndef VectorMath_Vector1_H
#define VectorMath_Vector1_H


namespace VectorMath {

class Vector1 {

public: // Methods:

    // This is a definition for a default constructor:
    Vector1() noexcept : m_x(0) {}

    // This is a declaration for another constructor:
    Vector1(float x) noexcept;

    // This is a declaration of a member function:
    Vector1 operator+(Vector1 const & rhs) const noexcept;

private: // Fields:

    float m_x;

}; // class Vector1

} // namespace VectorMath {

#endif // VectorMath_Vector1_H
// Vector1.cpp
#include "Vector1.h"


namespace VectorMath {

// Definition of the other constructor:
Vector1::Vector1(float x) noexcept
    : m_x(x)
{}

// Definition of the binary + operator:
Vector1 Vector1::operator+(Vector1 const & rhs) const noexcept
{ return m_x + rhs.m_x; }

} // namespace VectorMath {
jotik
  • 17,044
  • 13
  • 58
  • 123