c++ friend function implemented in a class can't access privates - c++

I'm trying to define 2 classes, declare a friend function in one of them and implement it in the other.
I am actually trying to get exactly what found in this post working:
How can friend function be declared for only one particular function and class?
I read the answer and thought it made sense.
then implemented it in my code and it gave me the errors:
Edited:
Error 1 error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup ...\MSVCRTD.lib(crtexe.obj) - (solved by adding main function)
Error 2 error LNK1120: 1 unresolved externals ...\Debug\Project.exe 1 1.. - (solved by adding main function)
Error 3 IntelliSense: member "one::data1" (declared at line 19) is inaccessible ...\Friends.cpp - (Exists even after cleaning and rebuilding project)
I thought it might be a problem with how I implemented it, so I did a copy-paste to the code in the answer:
class one;
class two
{
private:
int data2;
public:
two()
{
data2 = 200;
}
// this goes fine, because the function is not yet defined.
int accessboth(one a);
};
class one
{
private:
int data1;
public:
one()
{
data1 = 100;
}
friend int two::accessboth(one a);
};
// don't forget "inline" if the definition is in a header.
inline int two::accessboth(one a)
{
return (a.data1 + (*this).data2);
}
but I got the same error in the same place: a.data1 was inaccessible
I then searched and found more examples that suggest the same technique to solve the problem, but they all gave me the same inaccessible error in the same place...
Is there something I'm missing? should the provided example (suggested solution from previous post) work?
Something changed in the specification maybe?
thank you for any help.
D
P.S
I tried commenting on the previous post in order not to open a new question about this, but was unable to comment due to low reputation (I'm new here).

You are missing main function. Like this one for example:
int main() {
one a;
two b;
b.accessboth(a);
}
Put it on the bottom of your file and it should compile.

Related

Linking error with methods using class templates

I need to use my class template inside one of the member functions (class methods), as shown below :
Declaration :
template <int N>
class Array
{
private :
int var[N];
public :
void increment ();
};
Definition :
template <int N>
void Array<N> :: increment ()
{
for (int i = 0; i < N; i++)
{
cout << i << endl;
}
}
Instantiation and method call in Main.cpp:
Array <5>var;
int main()
{
var.increment();
system ("pause");
}
I keep getting a linking error saying "1 unresolved externals" in Main.obj (Main.cpp).
Please consider all "cout" and "using namespace std" to be already done in the background. I'm just adding the relevant code here.
My main problem is that I don't know how to use the class template parameter (N) inside one of the class's methods.
UPDATE: Sorry I'm late but I've found a solution to this. Thanks for the help all.
Just to close this thread because I forgot about it long ago. The problem seems to be the fact that templates can only be implemented in a header file of .tpp file. The link given by #user4581301 helped in clearing this up.
This is the link

LNK2019 Error with nested class in C++

I am new to C++, so I am sorry if this a simple or obvious error. I have been reading a lot other questions and the documentation, but I haven't been able to find a solution yet.
I am trying to add a new class definition to a large existing project. Everything compiles perfectly fine without my additions. However, when I add my code below I get a LNK2019 error on the constructor method (and any additional method). I have noticed adding/referencing properties does not cause this linker error, only the methods. Below is the most simple example that produces the error:
Header:
namespace foo
{
class bar_interface
{
public:
//My code
#ifndef Point_H
#define Point_H
class Point
{
public:
Point(int x, int y);
};
#endif
//existing code
void onStartup();
}
}
Class:
//My code
#ifndef Point_H
#define Point_H
class foo:bar_interface::Point{
public:
Point(int x, int y)
{
};
};
#endif
//existing code
void bar_interface::onStartup()
{
foo::bar_interface::Point p( (int)8, (int)8 );
//continue existing code
}
Error 1 error LNK2019: unresolved external symbol "public: __thiscall
foo::bar_interface::Point::Point(int,int)"
(??0Point#bar_interface#foo##QAE#HH#Z)
referenced in function "public: void __thiscall
foo::bar_interface::onStartup(void)"
(?onStartup#bar_interface#foo##QAEXXZ)
I realize that probably do not need such explicit calls to Point or casting the numbers as ints, but I wanted to make sure I wasn't missing anything obvious (removing them doesnt change the error). I have tried moving the 'Point' class to its own file and defining it outside the 'bar_interface' but within the 'foo' namespace. Removing the #ifndef code creates a C2011 redefinition error. I am at a loss for how to proceed.
Unresolved external means that the definition is missing, that is that the linker cannot find an implementation of the named function.
Somewhere you need:
namespace foo
{
bar_interface::Point::Point(int,int)
{ ... }
}
Remove all your lines from the code above that start from # and the reason of the issue becomes cleaner.

Linking failure within solution

EDIT: I know there are similar questions, but I cannot find an answer to a following issue: Why the methods inside the class are working correctly and outside are not.
I've got a weird problem in my project which I'm developing in MSVC++ 2012. My project consists of different modules of code. The important modules from the problem's point of view is a library and the GUI. They exist as different projects in the same solution.
I have some methods in the library which are part of the classes (in this case Calibration3D):
void Calibration3D::load(const std::string &path)
I use it without problems when I need it in the GUI, however I need to use a following method (outside the class):
void xxxyyy()
But when I'm trying to use that function (outside the class but in the same namespace) I get a following error:
1>project_xml.obj : error LNK2001: unresolved external symbol "void __cdecl cci::xxxyyy(void)" (?xxxyyy#cci##YAXXZ) 1>D:\praca_pw\cci\build-msvc2012\x64\Release\\ccigui.exe : fatal error LNK1120: 1 unresolved externals
Anybody knows how to solve it?
When I have a header file like this:
namespace xyz {
void foo();
class bar { ... };
}
then I write the cpp file like this:
#include "xyz.h"
namespace xyz {
void foo() { ... }
bar::bar() { ... }
}
This means I have to type a lot less and make fewer mistakes with regard to namespaces.
OK, solved, it seems that when a method is defined inside the namespace in header file, it should also be defined explicitly as part of namespace in implementation file, in this case:
cci::xxxyyy()
{
...
}
will work and
xxxyyy()
{
...
}
will not.

Is there a likely / common cause of a LNK2001 unresolved external symbol error when not using any outside libraries?

I am trying to create a new instance of a class, however I am receiving a LNK2001 unresolved external symbol error when I attempt to compile my code.
As far as I can tell I have written and included the class in exactly the same manner as I included another class, in both cases -
#include "class.h" // In main.cpp
class Class { // In class.h
private:
// etc.
public:
Class();
~Class();
// etc.
};
#include "class.h" // In class.cpp
Is there a common / likely cause of these errors, or a good way I might go about finding the source of the issue?
Edit: The error is
"Error 1 error LNK2019: unresolved external symbol "class Max
__cdecl max(void)" (?max##YA?AVMax##XZ) referenced in function _main main.obj Racing "
Edit: In both cases, a class is implemented across a .h and a .cpp file included in a project. The error is only appearing with one class.
Somewhere you have written this:
Max max();
What you intended was to declare a variable max of type Max.
C++ thinks you intend to declare a function max which returns an object of type Max. This is what it is looking for.
If you just say this:
Max max;
The issue will go away.
Edit: This only occurs with constructors which take no arguments. If the constructor takes arguments, C++ can see from the parameters (which will be rvalues, e.g. constants or expressions) that it is an instantiation of the class not a function declaration.
Max max(5); // Clearly cannot be a function, because 5 is an rvalue
Or
Max max(int); // Clearly cannot be an instantiation, because int is a type
But if the constructor takes no arguments, to distinguish between them, you have to drop the brackets if you are instantiating.

LNK2001 using a std::vector of a custom struct

I want to have some data cache which contains some objects which I can update over an UpdateCache function. However, I'm getting problems with a LNK2001 followed by a LNK1120.
HeaderFile.h
#ifndef headerfile_included
#define headerfile_included
#include <vector>
struct MyObject {
unsigned int A;
unsigned int B;
};
class MyClass {
private:
static std::vector<MyObject> myObjectCache;
public:
static void UpdateCache ();
};
#endif
CodeFile.cpp
#include "HeaderFile.h"
void MyClass::UpdateCache () {
myObjectCache.clear();
/* Repopulate cache with new data */
}
The error message I get from the linked is
error LNK2001: unresolved external symbol ""private: static class std::vector > MyClass::myObjectCache" (?myObjectCache#MyClass##0V?$vector#UMyObject##V?$allocator#UMyObject###std###std##A)".
fatal error LNK1120: 1 unresolved externals
My opinion is that it is some problem with the partitioning into the header file and the code file as I have had similar problems with improper partitioning. If it is again such a problem, it would be nice if you could post some rule on what to put into the header file and what into the code file since it's pretty confusing.
You need to add this to a cpp file:
std::vector<MyObject> MyClass::myObjectCache;
The reason is that as a static exists without a class ever being instantiated it needs to exist whether an instance of the class is instantiated or not. The line above creates the instance of the static and thus it exists whether or not you ever create an instance of the class itself.
Since your vector is static, essentially a global entity as far as the compiler is concerned, you need to be sure to give it a home in a compilation unit. That's why you have to do what #Goz says and do
std::vector<MyObject> MyClass::myObjectCache;