我是C ++的新手。我对Java和Python很满意,我正在尝试快速入门C ++。
我试图弄清楚如何声明/定义一个非成员函数,该函数通过引用获取类对象的参数。我无法编译我的代码。我试图在下面的三个文件集中复制问题。
我使用eclipse(Luna)作为IDE,而后者又在Ubuntu 14.04上使用g ++。在这个集合中,我在MyTest.h中的非成员函数的声明中得到了一个神秘的编译错误,就像这样 "声明中的明确资格< void mytest :: printInt(ostream&,MyTest&)"
在我的真实世界示例中,我在此函数的模拟定义(非声明)中得到了一个非常类似的错误。
最初我认为它与我有关,阻止编译器创建默认构造函数和" MyTest&米"某种程度上需要一个默认的构造函数(尽管这对我来说完全没有任何意义)。但声明和定义默认构造函数并不会改变问题。
我做错了什么? 什么是定义非成员函数的正确方法,该函数将类对象作为参数by-reference)? 从中可以获得哪些更大的教训?
在文件Mytest.h中:
#ifndef MYTEST_H_
#define MYTEST_H_
#include<iostream>
namespace mytest {
using std::ostream;
class MyTest {
public:
MyTest(int a) : a(a) {}
int getA() { return a; }
private:
int a;
};
void mytest::printInt(ostream& os, mytest::MyTest& m);
} /* namespace mytest */
#endif /* MYTEST_H_ */
在文件MyTest.cpp
中#include "MyTest.h"
namespace mytest {
void mytest::printInt(ostream& os, MyTest& m){
os << m.getA();
}
} /* namespace mytest */
最后一个文件运行它们,Test.cpp:
#include "MyTest.h"
using mytest::MyTest;
using std::cout;
using std::endl;
int main(void) {
MyTest a = MyTest(1);
mytest::printInt(cout, a);
}
答案 0 :(得分:6)
在printInt函数的声明和定义中删除&#34; mytest ::&#34;从功能名称。由于命名空间块,它已经在mytest命名空间中。
答案 1 :(得分:3)
在MyTest.h
和MyTest.cpp
替换
void mytest::printInt(ostream& os, mytest::MyTest& m)
与
void printInt(ostream& os, mytest::MyTest& m)
mytest::
不需要,因为您的声明和定义已经在命名空间块中。
另外,我建议使用Clang(有时)使用一些不那么神秘的错误消息。 Clang谈到这条线:
./MyTest.h:18:14: error: out-of-line declaration of 'printInt' does not match any declaration in namespace 'mytest'
void mytest::printInt(ostream& os, mytest::MyTest& m);
^~~~~~~~
vs GCC&#39>
MyTest.h:18:53: error: explicit qualification in declaration of ‘void mytest::printInt(std::ostream&, mytest::MyTest&)’
void mytest::printInt(ostream& os, mytest::MyTest& m);
答案 2 :(得分:1)
您不应在命名空间中添加命名空间限定符:
namespace mytest {
using std::ostream;
class MyTest {
public:
MyTest(int a) : a(a) {}
int getA() { return a; }
private:
int a;
};
// no namespace qualifier here
void printInt(ostream& os, MyTest& m);
} /* namespace mytest */
namespace mytest {
// no namespace qualifier here
void printInt(ostream& os, MyTest& m){
os << m.getA();
}
然后:
using mytest::MyTest;
using std::cout;
using std::endl;
int main(void) {
MyTest a = MyTest(1);
mytest::printInt(cout, a); // now use the namespace qualifier
}
答案 3 :(得分:0)
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
OBJS = Test.o MyTest.o
LIBS =
TARGET = Test
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
&#13;