如何防止 class 的重定义?
How to prevent Redefinition of class?
我一直在从一本最新的 C++ 书籍中实现自定义 Vector,但我在 vector.cpp 和 vector.h 文件中的 Class Vector 和 Vector::Vector 分别为: 'Vector'
的重新定义
这是每个文件的代码:
main.cpp:
#include <iostream>
#include "Vector.h"
#include "Container.h"
int main(int argc, const char * argv[]) {
return 0;
}
vector.h
class Vector {
public:
Vector(int s) :elem{new double[s]}, sz{s} // constructor: acquire resources
{
for (int i=0; i!=s; ++i) // initialize elements
elem[i]=0;
}
~Vector() { delete[] elem; } // destructor: release resources
double& operator[](int i);
int size() const;
private:
double* elem; // elem points to an array of sz doubles
int sz;
};
vector.cpp
Vector::Vector(int s) // definition of the constructor
:elem{new double[s]}, sz{s} // initialize members
{}
double& Vector::operator[](int i) // definition of subscripting
{
return elem[i];
}
int Vector::size() const // definition of size()
{
return sz;
}
container.cpp
class Container {
public:
virtual double& operator[](int) = 0; // pure virtual function
virtual int size() const = 0; // const member function (§4.2.1)
virtual ~Container() {} // destructor (§4.2.2)
};
class Vector_container : public Container { // Vector_container implements Container
public:
Vector_container(int s) : v(s) { } // Vector of s elements
~Vector_container() {}
double& operator[](int i) override { return v[i]; }
int size() const override { return v.size(); }
private:
Vector v;
};
我尝试用#ifndef Vector_h、#define Vector_h 和#endif 包含.h 文件,但错误仍然出现在Vector_cpp 中。如果我用#ifndef Vector_cpp、#define Vector_h和#endif封装Vector.cpp,错误仍然出现。
雪上加霜,当我将 Vector.h 添加到 container.cpp 时,它告诉我:未知类型名称 'Vector' 在我声明 Vector v
的底部
谁能帮我解决这个问题?
您还需要为您的容器 class 实现一个头文件,因此您也需要一个 Container.h
(注意这应该与文件名匹配)。在您的情况下,似乎只需将文件从 Container.cpp 重命名为 Container.h.
就足够了
此外,您应该将您的方法(例如 Vector
的构造函数)实现到一个文件中,而不是两个文件中。例如,您可以在头文件中声明方法,然后在源文件中定义它。
将所有内容放在一起,您需要:
- main.cpp(这里没有变化)
- Container.h(而不是Container.cpp,但内容没有变化
文件,你做得很好! :))
Vector.h
class Vector {
public:
Vector(int s);
~Vector();
double& operator[](int i);
int size() const;
private:
double* elem; // elem points to an array of sz doubles
int sz;
};
Vector.cpp
#include "Vector.h"
Vector::Vector(int s) :elem{new double[s]}, sz{s} // initialize members
{}
double& Vector::operator[](int i) // definition of subscripting
{
return elem[i];
}
int Vector::size() const // definition of size()
{
return sz;
}
Vector::~Vector() { delete[] elem; }
编译:
g++ main.cpp Vector.cpp
- 。通常的做法是遵循以下项目结构(使用 guards 指令):
ClassName1.h
#ifndef CLASSNAME1_H
#define CLASSNAME1_H
// class definition
class ClassName1
{
// ...
};
#endif
ClassName1.cpp
#include "ClassName1.h"
// implementation of ClassName1 functions may go here - except templates - templates should be defined eventually in one header file (not separate compilation unit) or one header with template body may include implementation from second header with implementation if template is big enough- extension , say - ipp. At least this is limitation for C++98.
ClassName1::someFunction()
{
// ...
}
Main.cpp // 或其他一些使用 ClassName1
的用户代码
#include "ClassName1.h"
ClassName1::someStaticFunction(); // for instance
ClassName1 className1; // for instance
在所有 class 系统中系统地遵循此结构,您将不会遇到 class 重新定义。这使得代码可移植。
2.There 是另一种非标准方式(Visual C++、GCC)——使用:#pragma once 指令
#pragma once
struct foo {
int member;
};
我一直在从一本最新的 C++ 书籍中实现自定义 Vector,但我在 vector.cpp 和 vector.h 文件中的 Class Vector 和 Vector::Vector 分别为: 'Vector'
的重新定义这是每个文件的代码:
main.cpp:
#include <iostream>
#include "Vector.h"
#include "Container.h"
int main(int argc, const char * argv[]) {
return 0;
}
vector.h
class Vector {
public:
Vector(int s) :elem{new double[s]}, sz{s} // constructor: acquire resources
{
for (int i=0; i!=s; ++i) // initialize elements
elem[i]=0;
}
~Vector() { delete[] elem; } // destructor: release resources
double& operator[](int i);
int size() const;
private:
double* elem; // elem points to an array of sz doubles
int sz;
};
vector.cpp
Vector::Vector(int s) // definition of the constructor
:elem{new double[s]}, sz{s} // initialize members
{}
double& Vector::operator[](int i) // definition of subscripting
{
return elem[i];
}
int Vector::size() const // definition of size()
{
return sz;
}
container.cpp
class Container {
public:
virtual double& operator[](int) = 0; // pure virtual function
virtual int size() const = 0; // const member function (§4.2.1)
virtual ~Container() {} // destructor (§4.2.2)
};
class Vector_container : public Container { // Vector_container implements Container
public:
Vector_container(int s) : v(s) { } // Vector of s elements
~Vector_container() {}
double& operator[](int i) override { return v[i]; }
int size() const override { return v.size(); }
private:
Vector v;
};
我尝试用#ifndef Vector_h、#define Vector_h 和#endif 包含.h 文件,但错误仍然出现在Vector_cpp 中。如果我用#ifndef Vector_cpp、#define Vector_h和#endif封装Vector.cpp,错误仍然出现。
雪上加霜,当我将 Vector.h 添加到 container.cpp 时,它告诉我:未知类型名称 'Vector' 在我声明 Vector v
的底部谁能帮我解决这个问题?
您还需要为您的容器 class 实现一个头文件,因此您也需要一个 Container.h
(注意这应该与文件名匹配)。在您的情况下,似乎只需将文件从 Container.cpp 重命名为 Container.h.
此外,您应该将您的方法(例如 Vector
的构造函数)实现到一个文件中,而不是两个文件中。例如,您可以在头文件中声明方法,然后在源文件中定义它。
将所有内容放在一起,您需要:
- main.cpp(这里没有变化)
- Container.h(而不是Container.cpp,但内容没有变化 文件,你做得很好! :))
Vector.h
class Vector { public: Vector(int s); ~Vector(); double& operator[](int i); int size() const; private: double* elem; // elem points to an array of sz doubles int sz; };
Vector.cpp
#include "Vector.h" Vector::Vector(int s) :elem{new double[s]}, sz{s} // initialize members {} double& Vector::operator[](int i) // definition of subscripting { return elem[i]; } int Vector::size() const // definition of size() { return sz; } Vector::~Vector() { delete[] elem; }
编译:
g++ main.cpp Vector.cpp
- 。通常的做法是遵循以下项目结构(使用 guards 指令):
ClassName1.h
#ifndef CLASSNAME1_H
#define CLASSNAME1_H
// class definition
class ClassName1
{
// ...
};
#endif
ClassName1.cpp
#include "ClassName1.h"
// implementation of ClassName1 functions may go here - except templates - templates should be defined eventually in one header file (not separate compilation unit) or one header with template body may include implementation from second header with implementation if template is big enough- extension , say - ipp. At least this is limitation for C++98.
ClassName1::someFunction()
{
// ...
}
Main.cpp // 或其他一些使用 ClassName1
的用户代码#include "ClassName1.h"
ClassName1::someStaticFunction(); // for instance
ClassName1 className1; // for instance
在所有 class 系统中系统地遵循此结构,您将不会遇到 class 重新定义。这使得代码可移植。
2.There 是另一种非标准方式(Visual C++、GCC)——使用:#pragma once 指令
#pragma once
struct foo {
int member;
};