What is needed for the simplest link transfer?

I am very new to C ++. I like Java and Python and I try to do a quick start in C ++.

I'm trying to figure out how to declare / define a non-member function that takes an argument to reference a class object. I am unable to compile my code. I tried to reproduce the problem in the set of 3 files below.

I am using eclipse (Luna) as IDE, which in turn uses g ++ on Ubuntu 14.04. In this set, I get a cryptic compilation error in the non-member function declaration in MyTest.h that looks like "Explicit qualification in the declaration" void mytest :: printInt (ostream &, MyTest &) "

In my real-life example, I get a very similar error in defining (not declaring) an analog of this function.

I originally thought it was because I was not letting the compiler create a default constructor, and "MyTest & m" somehow needs a default constructor (although it didn't make any sense to me at all). But declaring and defining the default constructor doesn't change the problem.

What am I doing wrong? What is the correct way to define a non-member function that takes class objects as arguments by reference)? What are some of the bigger lessons from this?

In the file 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_ */

      

In the file MyTest.cpp

#include "MyTest.h"

namespace mytest {

void mytest::printInt(ostream& os, MyTest& m){
    os << m.getA();
}

} /* namespace mytest */

      

And finally, the file to run, 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);
}

      

+3


source to share


4 answers


You shouldn't add a namespace qualifier from a namespace:

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();
}

      



Then:

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
}

      

+1


source


In the declaration and definition of the printInt function, remove "mytest ::" from the function name. It is already in the mytest namespace because of the namespace block.



+6


source


B MyTest.h

and MyTest.cpp

replace

void mytest::printInt(ostream& os, mytest::MyTest& m)

      

from

void printInt(ostream& os, mytest::MyTest& m)

      

mytest::

not required because your declaration and definition are already inside the namespace block.

On the side of the note, I recommend using Clang for (sometimes) a bit less critical error messages. Klang says about this line:

./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

MyTest.h:18:53: error: explicit qualification in declaration ofvoid mytest::printInt(std::ostream&, mytest::MyTest&)’
 void mytest::printInt(ostream& os, mytest::MyTest& m);

      

+3


source


Yoohoo, I got it. My Makefile was bad as Galik pointed out. Adding MyTest.o to the OBJS list fixed it.

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)
      

Run codeHide result


0


source







All Articles