问题三:类的头文件和实现文件分别写什么(用向量表示RGB输出“第一张图片”)

本文探讨了如何正确地在vec3.h和vec3.cpp文件中分配vec3类的声明与实现,确保编译无误并高效运行。通过遵循C++编程规范,明确了哪些部分应该出现在头文件中,哪些部分应该放置在实现文件中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

书上接下来是介绍一个表示向量的类(vec3)。所以,我要先创建一个新的类vec3。创建该类之后,生成两个文件:vec3.cpp和vec3.h。像之前一样,还是将书上的代码原封不动地抄写下来,如下:

#ifndefVEC3_H
#defineVEC3_H
 
#include<math.h>
#include<stdlib.h>
#include<iostream>
 
usingnamespace std;
 
class vec3
{
    public:
        vec3() {}
        vec3(float e0, float e1, float e2){e[0] = e0; e[1] = e1; e[2] = e2; }
        inline float x() const { return e[0]; }
        inline float y() const { return e[1]; }
        inline float z() const { return e[2]; }
        inline float r() const { return e[0]; }
        inline float g() const { return e[1]; }
        inline float b() const { return e[2]; }
 
        inline const vec3& operator+() const { return *this;}
        inline vec3 operator-() const { returnvec3(-e[0], -e[1], -e[2]); }
        inline float operator[](int i) const {return e[i]; }
        inline float& operator[](int i){return e[i]; };
 
        inline vec3& operator+=(const vec3 &v2);
        inline vec3& operator-=(const vec3&v2);
        inline vec3& operator*=(const vec3 &v2);
        inline vec3& operator/=(const vec3&v2);
        inline vec3& operator*=(const floatt);
        inline vec3& operator/=(const floatt);
 
        inline floatdot(const vec3 &v1, const vec3 &v2);
        inline vec3cross(const vec3 &v1, const vec3 &v2);
 
        inline float length() const
        {
            return sqrt(e[0]*e[0] + e[1]*e[1] +e[2]*e[2]);
        }
        inline float squared_length() const
        {
            return e[0]*e[0] + e[1]*e[1] +e[2]*e[2];
        }
        inline void make_unit_vector();
 
        float e[3];
};
 
inlinestd::istream& operator>>(std::istream &is, vec3 &t)
{
    is >> t.e[0] >> t.e[1] >>t.e[2];
    return is;
}
 
inlinestd::ostream& operator<<(std::ostream &os, const vec3 &t)
{
    os << t.e[0] << " "<< t.e[1] << " " << t.e[2];
    return os;
}
 
inline voidvec3::make_unit_vector()
{
    float k = 1.0 / sqrt(e[0]*e[0] + e[1]*e[1]+ e[2]*e[2]);
    e[0] *= k;
    e[1] *= k;
    e[2] *= k;
}
 
inline vec3operator+(const vec3 &v1, const vec3 &v2)
{
    return vec3(v1.e[0] + v2.e[0], v1.e[1] +v2.e[1], v1.e[2] + v2.e[2]);
}
 
inline vec3operator-(const vec3 &v1, const vec3 &v2)
{
    return vec3(v1.e[0] - v2.e[0], v1.e[1] -v2.e[1], v1.e[2] - v2.e[2]);
}
 
inline vec3operator*(const vec3 &v1, const vec3 &v2)
{
    return vec3(v1.e[0] * v2.e[0], v1.e[1] *v2.e[1], v1.e[2] * v2.e[2]);
}
 
inline vec3operator/(const vec3 &v1, const vec3 &v2)
{
    return vec3(v1.e[0] / v2.e[0], v1.e[1] /v2.e[1], v1.e[2] / v2.e[2]);
}
 
inline vec3 operator*(floatt, const vec3 &v)
{
    return vec3(t*v.e[0], t*v.e[1], t*v.e[2]);
}
 
inline vec3operator/(vec3 v, float t)
{
    return vec3(v.e[0]/t, v.e[1]/t, v.e[2]/t);
}
 
inline vec3operator*(const vec3 &v, float t)
{
    return vec3(t*v.e[0], t*v.e[1], t*v.e[2]);
}
 
inline float vec3::dot(const vec3 &v1, const vec3 &v2)
{
    return v1.e[0] * v2.e[0] + v1.e[1] *v2.e[1] + v1.e[2] * v2.e[2];
}
 
inline vec3 vec3::cross(const vec3 &v1, const vec3 &v2)
{
    return vec3( (v1.e[1]*v2.e[2] -v1.e[2]*v2.e[1]),
                 (v1.e[2]*v2.e[0] -v1.e[0]*v2.e[2]),
                 (v1.e[0]*v2.e[1] -v1.e[1]*v2.e[0]));
}
 
inline vec3&vec3::operator+=(const vec3 &v)
{
    e[0] += v.e[0];
    e[1] += v.e[1];
    e[2] += v.e[2];
 
    return *this;
}
 
inline vec3&vec3::operator*=(const vec3 &v)
{
    e[0] *= v.e[0];
    e[1] *= v.e[1];
    e[2] *= v.e[2];
 
    return *this;
}
 
inlinevec3& vec3::operator-=(const vec3 &v)
{
    e[0] -= v.e[0];
    e[1] -= v.e[1];
    e[2] -= v.e[2];
 
    return *this;
}
 
inlinevec3& vec3::operator/=(const vec3 &v)
{
    e[0] /= v.e[0];
    e[1] /= v.e[1];
    e[2] /= v.e[2];
 
    return *this;
}
 
inlinevec3& vec3::operator*=(const float t)
{
    e[0] *= t;
    e[1] *= t;
    e[2] *= t;
 
    return *this;
}
 
inlinevec3& vec3::operator/=(const float t)
{
    float k = 1.0 / t;
    e[0] *= k;
    e[1] *= k;
    e[2] *= k;
 
    return *this;
}
 
inline vec3unit_vector(vec3 v)
{
    return v / v.length();
}
 


另外,书上给的main函数:

    #include <iostream>
    #include <fstream>
    #include "vec3.h"

    using namespace std;

    int main()
    {
        int nx = 200;
        int ny = 100;

        ofstream outfile( ".\\results\\FirstImage2.txt", ios_base::out);
        outfile << "P3\n" << nx << " " << ny << "\n255\n";

        std::cout << "P3\n" << nx << " " << ny << "\n255\n";
        for (int j = ny-1; j >= 0; j--)
        {
            for (int i = 0; i < nx; i++)
            {
                vec3 col(float(i) / float(nx), float(j) / float(ny), 0.2);

                int ir = int (255.99*col[0]);
                int ig = int (255.99*col[1]);
                int ib = int (255.99*col[2]);

                outfile << ir << " " << ig << " " << ib << "\n";
                std::cout << ir << " " << ig << " " << ib << "\n";
            }
        }
    }


问题来了,vec3类的这些代码该放哪呢?vec3.cppor vec3.h?老实说,凭感觉全部写在了vec3.cpp中。但是,编译出错了。不知道该怎么办了。国外问谷哥,国内找度娘。

http://www.cnblogs.com/ider/archive/2011/06/30/what_is_in_cpp_header_and_implementation_file.html

得知:

 

非模板类型(none-template)

模板类型(template)

头文件(.h)

全局变量申明(带extern限定符)

全局函数的申明

inline限定符的全局函数的定义

inline限定符的全局模板函数的申明和定义

类的定义

类函数成员和数据成员的申明(在类内部)

类定义内的函数定义(相当于inline

static const限定符的数据成员在类内部的初始化

inline限定符的类定义外的函数定义

模板类的定义

模板类成员的申明和定义(定义可以放在类内或者类外,类外不需要写inline)

实现文件(.cpp)

全局变量的定义(及初始化)

全局函数的定义

(无)

类函数成员的定义

类带static限定符的数据成员的初始化

 

以此为据,vec3类的这些代码就应该全部放在vec3.h中,vec3.cpp就空着吧。编译运行后的结果和“问题二:输出第一张图片”是一样的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值