Example I have a program:
class TestStatic
{
private:<br>
static int staticvariable;
public:<br>
TestStatic() {
this->staticvariable = 0;
cout << this->staticvariable;
}
~TestStatic() {}
};
int main() {
TestStatic object;
return 0;
}
why this pointer can't access staticvariable . I don't understand why.
Probably because staticvariable is not bound to this but to your class.
Check out the following answers:
Accessing static class variables in C++?
Undefined reference to static class member
Hope it helps.
Related
I want to use the nlohmann/json library to serialize some json to a QObject and vice versa.
The problem I run into is that the parser is trying to use the copy constructor of the QObject, wish is not allowed.
There is something in the documentation regarding this https://github.com/nlohmann/json#how-can-i-use-get-for-non-default-constructiblenon-copyable-types but I can't manage to make it work.
template <>
struct adl_serializer<MyQObject>
{
static MyQObject from_json(const json& j)
{
return {j.get<MyQObject>()}; // call to implicitly-deleted copy constructor of 'MyQObject'
}
static void to_json(json& j, MyQObject t)
{
j = t; // no viable overload '='
}
};
inline void from_json(const json& j, MyQObject& x)
{
x.setXxx(j.at("xxx").get<typeOfXxx>()):
// ...
}
inline void to_json(json& j, const MyQObject& x)
{
j = json::object();
j["xxx"] = x.xxx();
// ...
}
What should I write in the adl_serializer to make it work ?
I am developing a library which has two layers, unmanaged (C++) and managed (C++/CLI). The unmanaged layer contains the logics and the computation algorithms, while the managed layer provides interface and visualisation to a .NET-based host application. A class in the managed layer wraps its class counterpart in the unmanaged layer, e.g. ManagedA wraps UnmanagedA and ManagedB wraps UnmanagedB.
Classes in the unmanaged layer have query methods, suppose UnmanagedA::B() returns an instance of UnmanagedB. For visualisation, I need to wrap this instance in a ManagedB instance. The problem is, if I repeat this process twice, I am creating two ManagedB instances which points to the same UnmanagedB instance. Because the ManagedB instances are disposed, the same UnmanagedB instance is deleted twice, which should not happen.
So I would like to know the best practice or strategy to wrap an unmanaged object in a managed object.
Here is a code which emulates this behaviour. I understand that you don't need to explicitly delete the managed objects, but I use it here just to emulate the deletion sequence.
Many thanks.
#include "stdafx.h"
using namespace System;
class UnmanagedB
{
public:
UnmanagedB() {}
~UnmanagedB() {}
int i = 0;
};
class UnmanagedA
{
public:
UnmanagedA(UnmanagedB* pUnmanagedB)
: m_pUnmanagedB(pUnmanagedB)
{
}
~UnmanagedA() {}
UnmanagedB* B() { return m_pUnmanagedB; }
protected:
UnmanagedB* m_pUnmanagedB;
};
public ref class ManagedA : IDisposable
{
public:
ManagedA(UnmanagedA* pUnmanagedA)
: m_pUnmanagedA(pUnmanagedA)
{
}
~ManagedA()
{
delete m_pUnmanagedA;
}
private:
UnmanagedA* m_pUnmanagedA;
};
public ref class ManagedB : IDisposable
{
public:
ManagedB(UnmanagedB* pUnmanagedB)
: m_pUnmanagedB(pUnmanagedB)
{
}
~ManagedB()
{
delete m_pUnmanagedB;
}
private:
UnmanagedB * m_pUnmanagedB;
};
int main(array<System::String ^> ^args)
{
UnmanagedB* pUnmanagedB = new UnmanagedB();
UnmanagedA* pUnmanagedA = new UnmanagedA(pUnmanagedB);
ManagedB^ pManagedB1 = gcnew ManagedB(pUnmanagedA->B());
ManagedB^ pManagedB2 = gcnew ManagedB(pUnmanagedA->B());
delete pManagedB1;
delete pManagedB2; // will crash here because the destructor deletes pUnmanagedB, which is already deleted in the previous line
delete pUnmanagedA;
return 0;
}
This is a typical case using a smart pointer.
So don't store UnmanagedA* and UnmanagedB* use shared_ptr and shared_ptr
Becaus ethe managed class can only carry a plain pointer to an unmannged class you have to redirect it again and use:
shared_ptr<UnmanagedA>* pManagedA;
A simple accessor function will help you to use the pointer:
shared_ptr<UnmanagedA> GetPtrA() { return *pManagedA; }
All plain pointer to the unmanaged classes should be shared_ptr instances. In your main use make_shared instead of new. Or direct the pointer created by new into a shared_ptr...
Here is one class rewritten:
public ref class ManagedA : IDisposable
{
public:
ManagedA(shared_ptr<UnmanagedA> pUnmanagedA)
{
m_pUnmanagedA = new shared_ptr<UnmanagedA>();
*m_pUnmanagedA = pUnmanagedA;
}
~ManagedA()
{
delete m_pUnmanagedA;
}
void Doit()
{
GetPtrA()->DoSomething();
}
private:
shared_ptr<UnmanagedA>* m_pUnmanagedA;
shared_ptr<UnmanagedA> GetPtrA() { return *m_pUnmanagedA; }
};
I have a function which calls emitResult after loading data from file.
bool IpResolver::ResolvedInfo::load(QTextStream &in)
{
ResolvedInfo rf;
while (!in.atEnd())
{
QString line = in.readLine();
QStringList list = line.split(' ');
list[0] = rf.country;
list[1] = rf.ip;
if (rf.ip.isEmpty() == false)
{
emitResult(rf);
}
}
}
So here is declaration of emitResult:
private:
void emitResult(const ResolvedInfo &data);
And it gives me this error:
a nonstatic member reference must be relative to a specific object
No idea what should I do.
emitResult is a non-static member function of IpResolver, I presume. Yet you're calling it without any instance, from a subclass IpResolver::ResolvedInfo. Remember that just because the ResolvedInfo is a subclass, doesn't make it special in any other way. Specifically, if it doesn't hold a reference to the instance of the parent class, it won't work the way you expect it to.
There are two general ways to fix your issue:
You can pass a reference to IpResolver to the ResolvedInfo constructor, and retain the reference in the ResolvedInfo instance:
class IpResolver {
class ResolvedInfo {
IpResolver & q;
public:
ResolvedInfo(IpResolver & q) : q(q) { ... }
static bool load(QTextStream &in) {
ResolvedInfo rf;
while (!in.atEnd())
{
QString line = in.readLine();
QStringList list = line.split(' ');
list[0] = rf.country;
list[1] = rf.ip;
if (!rf.ip.isEmpty())
q.emitResult(rf);
}
}
};
void emitResult(const ResolvedInfo &);
...
};
Or you can make the emitResult a static method:
class IpResolver {
...
static void emitResult(const ResolvedInfo &);
};
I have the following code in Visual C++:
#using <mscorlib.dll>
using namespace System;
__gc class classEx
{
public:
classEx()
{
data = "abcd";
}
classEx(String *s)
{
data=s;
}
String* getNombre()
{
return data;
}
void setNombre(String *s)
{
data=s;
}
private:
String* data;
};
int main(void)
{
classEx* obj = new classEx();
return 0;
}
I have changed the Configuration Manager to Release and Build is checked. The problem is when I try to compile it appears a bunch of errors, such as:
error C4980: '__gc' : use of this keyword requires /clr:oldSyntax command line option
cannot use this indirection on type 'System::String'
The last error points that I cannot use in the second constructor the String *s. Why is that?
Is there something that I am missing?
If you will set a corresponding compiler option to clr:oldsyntax in the project properties as the first message says, then the following code compiles without errors in Visual Studio 2010:
#include "stdafx.h"
using namespace System;
__gc class A
{
public:
A( String *s ) : data( s ) {}
String * get_data() { return data; }
private:
String *data;
};
int main()
{
A *pa = new A( "Hello World" );
Console::WriteLine( pa->get_data() );
return 0;
}
It seems that the second message is the result of that you did not set the option pointed out in the first message.
You should select menu Project → Properties → General → *Supporting of CLR (or something else because I have the Russian release of Visual Studio 2010 I can not name the option exactly in English) → clr:oldsyntax
You need to use different syntax for managed code (not the * operator):
String ^ data;
You'll also need the /clr command line option.
This article has a wealth of examples:
String (C++/CLI and C++/CX)
i have installed Academic version of pex and roles .
I wrote the following code in Visual Studio 2010.but pex just gave a null pointer as the input. doesn't the pex support the class type? please help me.
the test inferface is Test.
source code:
public class ClassForPex
{
public int a;
public int b;
ClassForPex(int x, int y)
{
a = x;
b = y;
}
};
public static class StringExtensions
{
public static int Test(ClassForPex cjh)
{
if (cjh.a > cjh.b)
return cjh.a;
else
{
return cjh.b;
}
}
}
You'll need to use a factory for supplying your ClassForPex instances to the tests. Look at this article to see how to do that.
Using of Factory in Pex - http://developers.de/blogs/damir_dobric/archive/2009/04/13/using-of-factory-in-pex.aspx