【问题标题】:C++ error redefinition of function in spite of using #ifndef尽管使用#ifndef,但函数的C++错误重新定义
【发布时间】:2021-07-21 03:53:28
【问题描述】:

我已经尝试了几次来消除错误,其中之一是使用#ifndef,但它还没有奏效。请帮忙!

vec3.h 文件

    #ifndef VEC3_H
#define VEC3_H

#include <cmath>
#include <iostream>

using std::sqrt;

class vec3 {
    public:
        vec3() : e{0,0,0} {}
        vec3(double e0, double e1, double e2) : e{e0, e1, e2} {}

        double x() const { return e[0]; }
        double y() const { return e[1]; }
        double z() const { return e[2]; }

        vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); }
        double operator[](int i) const { return e[i]; }
        double& operator[](int i) { return e[i]; }

        vec3& operator+=(const vec3 &v) {
            e[0] += v.e[0];
            e[1] += v.e[1];
            e[2] += v.e[2];
            return *this;
        }

        vec3& operator*=(const double t) {
            e[0] *= t;
            e[1] *= t;
            e[2] *= t;
            return *this;
        }

        vec3& operator/=(const double t) {
            return *this *= 1/t;
        }

        double length() const {
            return sqrt(length_squared());
        }

        double length_squared() const {
            return e[0]*e[0] + e[1]*e[1] + e[2]*e[2];
        }

    public:
        double e[3];
};

// Type aliases for vec3
using point3 = vec3;   // 3D point
using color = vec3;    // RGB color

#endif
  
  
    // vec3 Utility Functions

inline std::ostream& operator<<(std::ostream &out, const vec3 &v) {
    return out << v.e[0] << ' ' << v.e[1] << ' ' << v.e[2];
}

inline vec3 operator+(const vec3 &u, const vec3 &v) {
    return vec3(u.e[0] + v.e[0], u.e[1] + v.e[1], u.e[2] + v.e[2]);
}

inline vec3 operator-(const vec3 &u, const vec3 &v) {
    return vec3(u.e[0] - v.e[0], u.e[1] - v.e[1], u.e[2] - v.e[2]);
}

inline vec3 operator*(const vec3 &u, const vec3 &v) {
    return vec3(u.e[0] * v.e[0], u.e[1] * v.e[1], u.e[2] * v.e[2]);
}

inline vec3 operator*(double t, const vec3 &v) {
    return vec3(t*v.e[0], t*v.e[1], t*v.e[2]);
}

inline vec3 operator*(const vec3 &v, double t) {
    return t * v;
}

inline vec3 operator/(vec3 v, double t) {
    return (1/t) * v;
}

inline double dot(const vec3 &u, const vec3 &v) {
    return u.e[0] * v.e[0]
         + u.e[1] * v.e[1]
         + u.e[2] * v.e[2];
}

inline vec3 cross(const vec3 &u, const vec3 &v) {
    return vec3(u.e[1] * v.e[2] - u.e[2] * v.e[1],
                u.e[2] * v.e[0] - u.e[0] * v.e[2],
                u.e[0] * v.e[1] - u.e[1] * v.e[0]);
}

inline vec3 unit_vector(vec3 v) {
    return v / v.length();
}

主文件,chap_3.cpp

    #include "color.h"
#include "ray.h"
#include "vec3.h"

#include <iostream>


color ray_color(const ray& r) {
    vec3 unit_direction = unit_vector(r.direction());
    auto t = 0.5*(unit_direction.y() + 1.0);
    return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0);
}

int main() {

    // Image

    const auto aspect_ratio = 16.0 / 9.0;
    const int image_width = 400;
    const int image_height = static_cast<int>(image_width / aspect_ratio);

    // Camera

    auto viewport_height = 2.0;
    auto viewport_width = aspect_ratio * viewport_height;
    auto focal_length = 1.0;

    auto origin = point3(0, 0, 0);
    auto horizontal = vec3(viewport_width, 0, 0);
    auto vertical = vec3(0, viewport_height, 0);
    auto lower_left_corner = origin - horizontal/2 - vertical/2 - vec3(0, 0, focal_length);

    // Render

    std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";

    for (int j = image_height-1; j >= 0; --j) {
        std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
        for (int i = 0; i < image_width; ++i) {

            auto u = double(i) / (image_width-1);
            auto v = double(j) / (image_height-1);
            ray r(origin, lower_left_corner + u*horizontal + v*vertical - origin);
            color pixel_color = ray_color(r);

            write_color(std::cout, pixel_color);
        }
    }

    std::cerr << "\nDone.\n";
}

如何解决错误,如下所示:

enter codevec3.h: In function 'vec3 operator+(const vec3&, const vec3&)':
vec3.h:65:17: error: redefinition of 'vec3 operator+(const vec3&, const vec3&)'
 inline vec3 operator+(const vec3 &u, const vec3 &v) {
             ^~~~~~~~
In file included from color.h:4:0,
             from chap_3.cpp:1:
vec3.h:65:17: note: 'vec3 operator+(const vec3&, const vec3&)' previously defined here
     inline vec3 operator+(const vec3 &u, const vec3 &v) {
                 ^~~~~~~~ here

我尝试了多个来源,但均无济于事,而且我从受信任的来源中选择了代码,并且只进行了微小的更改,因此我无法理解错误发生的原因。

【问题讨论】:

  • include guards 需要保护整个头文件,而不仅仅是它的一部分。
  • 这些功能不在您的#ifdef 保护范围内。不使用这些过时的结构的好案例,并使用#pragma once 正确编码。
  • 一般经验法则:当您遇到此类问题时,请备份您的代码并开始破解代码。当问题突然消失时,错误很可能出现在您刚刚删除的部分。更仔细地检查它。

标签: c++ function object oop


【解决方案1】:

您的内联定义位于头文件其余部分的#ifndef/#endif 之后,这意味着每个#include 都会获取它们。你可以

  1. #endif 移动到头文件的最后,或者
  2. 使用 #pragma once 代替包含保护(不是标准的,但大多数编译器都支持它)。

【讨论】:

  • 并不是once 也可以被具有足够复杂目录结构的构建环境所欺骗。这些天来,once 支持编译器非常聪明,你很少看到这一点。但是,当它发生时真的很糟糕。
  • @user4581301 是的,但我认为你更可能遇到#ifndef 命名冲突而不是#pragma once 的问题。
  • 说实话,我遇到不支持once 的编译器比命名冲突或once 破坏构建环境更常见。
  • 感谢您的解决方案!
猜你喜欢
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 2023-03-10
相关资源
最近更新 更多