在c ++中编译类时出错

时间:2015-07-17 15:54:47

标签: c++ oop compilation compiler-errors

我试图在c ++中为三维向量创建一个类,但是有一些错误。之前我在python中学过一点oop,但我对oop和c ++还是很新的。我创建了头文件threevector.h,类为threevector.cpp的文件和主程序文件main.cpp。我只是想知道我做错了什么。

// threevector.h
#ifndef THREEVECTOR_H
#define THREEVECTOR_H
#include <iostream>

class threevector {
    private:
        double xcoord, ycoord, zcoord;

    public:
        threevector();
        threevector(double x, double y, double z, char type);
        void print ();      
};
#endif // THREEVECTOR_H


//threevector.cpp
#include "threevector.h"
#include <cmath>

threevector() {
    xcoord = 0.0;
    ycoord = 0.0;
    zcoord = 0.0;
}

threevector(double x, double y, double z, char type) {
    if (type == 'c') {
        // cartesian coordinate
        xcoord = x;
        ycoord = y;
        zcoord = z;
    } 
    else if (type == 'p') {
        // polar coordinate
        // x = r, y = phi, z = theta
        xcoord = x*sin(y)*cos(z);
        ycoord = x*sin(y)*sin(z);
        zcoord = x*cos(y);
        }
}

void print () {
    std::cout << xcoord << '\t' << ycoord << '\t' << zcoord << std::endl;
}


// main.cpp
#include "threevector.h"
#include <cmath>
#include <iostream>

using namespace std;

int main() {
    threevector v0;
    v0.print();

    threevector v1(-1,2,4.384,'c');
    cout << "v1 = ";
    v1.print();

    return 0;
}

以下是我收到的错误消息:

main.cpp(.text+0x15): undefined reference to 'threevector::threevector()'
main.cpp(.text+0x15): undefined reference to 'threevector::print()'
main.cpp(.text+0x15): undefined reference to 'threevector::threevector::threevector(double, double, double, char)'
main.cpp(.text+0x15): undefined reference to 'threevector::print()'
[Error] ld returned 1 exit status

2 个答案:

答案 0 :(得分:4)

您定义了threevector的方法错误。它应该是:

threevector::threevector() {
    xcoord = 0.0;
    ycoord = 0.0;
    zcoord = 0.0;
}

threevector::threevector(double x, double y, double z, char type) {
    if (type == 'c') {
        // cartesian coordinate
        xcoord = x;
        ycoord = y;
        zcoord = z;
    } 
    else if (type == 'p') {
        // polar coordinate
        // x = r, y = phi, z = theta
        xcoord = x*sin(y)*cos(z);
        ycoord = x*sin(y)*sin(z);
        zcoord = x*cos(y);
        }
}

void threevector::print () {
    std::cout << xcoord << '\t' << ycoord << '\t' << zcoord << std::endl;
}

所有threevector的方法都在threevector的范围内。

不要忘记将其编译为main.cpp

g++ threevector.cpp main.cpp

threevector位于同一目标文件中时,这将正确链接。

答案 1 :(得分:1)

您尚未定义成员函数,只是声明了它们。

如果你再次查看你的课程定义:

threevector::threevector()

它包含三个成员函数的声明:

  • threevector::threevector(double, double, double, char)
  • threevector::print()
  • threevector::

threevector::部分很重要 - 因为这些是成员函数,类名是他们自己名字的一部分(或者可以这么说)。

但是,您定义的功能会错过print()部分。例如,您定义了一个名为threevector::print()的函数,但名称只是巧合。

print()threevector::threevector() { xcoord = 0.0; ycoord = 0.0; zcoord = 0.0; } threevector::threevector(double x, double y, double z, char type) { if (type == 'c') { // cartesian coordinate xcoord = x; ycoord = y; zcoord = z; } else if (type == 'p') { // polar coordinate // x = r, y = phi, z = theta xcoord = x*sin(y)*cos(z); ycoord = x*sin(y)*sin(z); zcoord = x*cos(y); } } void threevector::print () { std::cout << xcoord << '\t' << ycoord << '\t' << zcoord << std::endl; } 是不同的名称,因此功能不同。

与两个构造函数相同。

因此,在定义函数时,解决方案是使用正确的全名:

threevector::threevector() :
    xcoord(0.0),
    ycoord(0.0),
    zcoord(0.0)
{
}

虽然我们应该使用它,但构造函数应该使用初始化列表,而不是赋值,至少如果这很容易的话:

Wearable.ChannelApi.openChannel(
        mGoogleApiClient, node.getId(), "/mypath").setResultCallback(
        new ResultCallback<ChannelApi.OpenChannelResult>() {
            @Override
            public void onResult(ChannelApi.OpenChannelResult openChannelResult) {
                if (openChannelResult.getStatus().isSuccess()) {
                    mChannel = openChannelResult.getChannel();
                    mChannel.getOutputStream(mGoogleApiClient).setResultCallback(

                            new ResultCallback<Channel.GetOutputStreamResult>() {
                                @Override
                                public void onResult(Channel.GetOutputStreamResult getOutputStreamResult) {
                                    if (getOutputStreamResult.getStatus().isSuccess()) {
                                        mOutputStream = getOutputStreamResult.getOutputStream();
                                    } else {
                                        // handle failure, and close channel
                                    }
                                }
                            });
                }
            }
        });

P.S。:不要将此与名称空间混淆。所有这些都与名称空间无关。