i try to use std::map as property in my class. I use Visual Studio 2012, and my class is like:
public ref class MyClass
{
std::map<std::wstring,MyType> * mpMyMap;
MyClass()
{
mpMyMap = new std::map<std::wstring,MyType>();
}
~MyClass()
{
delete mpMyMap;
}
Get(std::wstring name)
{
return mpMyMap[name];
}
}
At return mpMyMap[name]; I get error, what there is no operator[] for this type. What should I do?
the bracket operator is on the map, not on the pointer of a map...
Try : return (*mpMyMap)[name];
The correct syntax is
MyType Get(std::wstring name)
{
return (*mpMyMap)[name];
}
You could also make the map an instance member instead of a pointer
std::map<std::wstring,MyType> mMyMap;
then your original code in Get would work and you'd get rid of memory management in the constructor and the destructor of MyClass.
Use
return (*mpMyMap)[name];
or
return mpMyMap->operator[]( name );
P.S. What is this
public ref class MyClass
//^^^^^^^^^^
Also, add return type for Get (MyType in your case)
mpMyMap is a pointer (for which I can see no reason), so you need to dereference it:
return (*mpMyMap)[name];
If mpMyMap must be a dynamically allocated remember to delete it in the destructor and either prevent copying of MyClass or implement copy constructor and assignment operator.
Note Get() is missing a return type (which should be either MyType or MyType&). Make the argument to Get() a const std::wstring& to avoid unnecessary copying and const as Get() does not modify it.
Since mpMyMap is pointer first variant is
Get(std::wstring name)
{
return (*mpMyMap)[name];
}
And second
Get(std::wstring name)
{
return mpMyMap->operator[](name);
}
And Get should have return-type.
Related
Error pic
Why compiler tells me it doesn't exist? I have last SDK installed and netcoreapp3.1 as targeted framework.
public SomeDefinedType[] GetRecords()
{
return new System.Array.Empty<SomeDefinedType>();
}
Array.Empty() is a function that returns an empty array, not a type. It can't be used with new. Just return the function's result:
public SomeDefinedType[] GetRecords()
{
return System.Array.Empty<SomeDefinedType>();
}
Generally, a lot of code does nothing but get/set class members. For that I implemented a simple container class to have getters and setters associated
to a "field". At a first sight this looks pretty ok and results in far less code. This is how the container class looks like:
Member.h
#include <functional>
template <class T>
class Member
{
public:
T data;
using Getter_t = std::function<T(void)>;
using Setter_t = std::function<void(T)>;
using Notify_t = std::function<void(void)>;
Setter_t m_setterFunc;
Getter_t m_getterFunc;
Notify_t m_notifyFunc;
Member()
{
this->m_getterFunc = [=] (void) -> T { return this->data; };
this->m_setterFunc = [=] (T data) -> void { this->data = data; };
this->m_notifyFunc = [] (void) -> void { };
}
auto get() -> T { return this->m_getterFunc(); }
auto set(T data) -> void { this->m_setterFunc(data); this->m_notifyFunc(); }
auto getter(Getter_t func) -> Member& { this->m_getterFunc = func; return *this; }
auto setter(Setter_t func) -> Member& { this->m_setterFunc = func; return *this; }
auto notify(Notify_t func) -> Member& { this->m_notifyFunc = func; return *this; }
~Member() { }
};
I know some things are not perfect yet but that's okay for now. The next few lines show how Member instances are defined and the simple and convenient way to access underlying data. get, set and notify functions can be replaced by lambdas or function pointers to override custom behavior.
main.cpp
#include <iostream>
#include "Member.h"
class MyClass
{
public:
Member<int> foo;
Member<std::string> bar;
void barChanged() { std::cout << "bar changed\n"; }
};
auto main(int argc, const char * argv[]) -> int
{
MyClass instance;
instance.foo.notify([] () -> void { std::cout << "foo changed\n"; });
instance.bar.notify(std::bind(&MyClass::barChanged, instance));
instance.foo.set(10);
instance.bar.set("some string");
std::cout << instance.foo.get() << " " << instance.bar.get() << std::endl;
return 0;
}
The problem now is that the Q_PROPERTY macro expects function names for the READ and WRITE accessors and I'm back at where I started: I have to write get and set functions for each property explicitly. Exactly what I wanted to avoid.
class MyOtherClass : public QObject
{
Q_OBJECT
Q_PROPERTY(bool flag READ getFlag WRITE setFlag NOTIFY flagChanged);
public:
Member<bool> m_flag;
auto getFlag() -> bool { return m_flag.get(); }
auto setFlag(bool flag) -> void { this->m_flag.set(flag); }
};
Is it possible to directly use the already existing m_flag.get and m_flag.set functions? I tried the obvious things but they were either rejected by the moc or resulted in too much code.
Edit
As mentioned below, the MEMBER keyword makes it possible to have properties without specifying get and set functions. However, private members then only can be accessed by their names (this->property("myPropertyName")) and also there's no way to achieve more than "plain" get and set.
To make it more clear: The motivation is not to just avoid writing get and set functions but trying to implement a flexible member system which
by default performs get/set as expected
supports custom logic (for example forward newly set values to some other instance)
can be used for C++ class members and is compatible with Qt properties
And the only missing piece is the bridge between the Q_PROPERTY READ/WRITEaccessors and the get/set methods of the Member class.
Thanks for any help!
I don't think that it's possible to redirect READ or WRITE property methods to some other internal or external object without writing wrappers, but if your getters and setters do not do anything except return or set data: there is MEMBER variable association at least in latest Qt versions.
From Qt Doc:
Q_PROPERTY(type name
(READ getFunction [WRITE setFunction] |
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
A READ accessor function is required if no MEMBER variable was
specified. It is for reading the property value. Ideally, a const
function is used for this purpose, and it must return either the
property's type or a const reference to that type. e.g.,
QWidget::focus is a read-only property with READ function,
QWidget::hasFocus().
A WRITE accessor function is optional. It is for setting the property
value. It must return void and must take exactly one argument, either
of the property's type or a pointer or reference to that type. e.g.,
QWidget::enabled has the WRITE function QWidget::setEnabled().
Read-only properties do not need WRITE functions. e.g., QWidget::focus
has no WRITE function.
A MEMBER variable association is required if no READ accessor function
is specified. This makes the given member variable readable and
writable without the need of creating READ and WRITE accessor
functions. It's still possible to use READ or WRITE accessor functions
in addition to MEMBER variable association (but not both), if you need
to control the variable access.
Using MEMBER you do not need to write getters and setters.
In C++11, two types of "managed" pointer types were introduced - shared_ptr and unique_ptr. Let's now assume we have a set of classes that support a clone() method, such as foo->clone() would return a copy of the foo object. If your goal was to return a managed pointer from the clone() method, how would you allow the user of the interface to select which kind of pointer he wants to be returned?
As a sub-question, would you rather return a raw pointer from the clone() method and let the user construct either shared_ptr or unique_ptr by himself? If not, why?
The standard smart pointer to manage a dynamic allocation is always unique_ptr. By contrast, shared_ptr is a very specific tool with specialized features (e.g. type-erased deleter, weak pointer observers) and higher costs (virtual dispatch, locked atomic operations) that should only be used when you definitely know you want it. Public raw pointers are a taboo out of principle, and so the natural clone interface looks like this:
struct Base
{
// must have virtual destructor to destroy through base pointer
virtual ~Base() {}
// non-leaf classes are abstract
virtual std::unique_ptr<Base> clone() const = 0;
};
struct Derived : Base
{
virtual std::unique_ptr<Base> clone() const override
{
return std::unique_ptr<Derived>(new Derived(*this));
// or "return std::make_unique<Derived>(*this)" in C++14
}
};
(Unfortunately, we cannot use any kind of covariant return types here, since the template classes unique_ptr<Base> and unique_ptr<Derived> are unrelated. If you prefer to have a clone function that returns the derived type, you could add a non-virtual function like direct_clone that returns a std::unique_ptr<Derived>, and implement the virtual clone() in terms of that.)
Something along this lines would give you the means to select the kind of smart pointer returned. Would probably be better if encapsulated in a mixin Clonable class template, for maintainability and reusability of the idea.
#include <iostream>
#include <memory>
class Base {
public:
virtual ~Base() {
std::cout << "deleting Base\n";
}
template <template <typename ...Args> class SmartPtr>
SmartPtr<Base> clone() {
return SmartPtr<Base>(this->inner_clone());
}
virtual void speak() const = 0;
private:
virtual Base *inner_clone() const = 0;
};
class C: public Base {
public:
~C() {
std::cout << "deleting C\n";
}
template <template <typename ...Args> class SmartPtr>
SmartPtr<C> clone() {
return SmartPtr<C>(this->inner_clone());
}
void speak() const {
std::cout << "I am C and I inherit from Base!\n";
}
private:
C *inner_clone() const override {
return new C(*this);
}
};
// End boilerplate.
int main()
{
auto original = C{};
// the declarations below should use auto, and are just explicitly typed to
// show the correct return type of clone();
std::shared_ptr<C> shared = original.clone<std::shared_ptr>();
std::unique_ptr<C> unique = original.clone<std::unique_ptr>();
// the declarations below show it working through conversion to a base class
// smart pointer type
std::shared_ptr<Base> sharedBase = original.clone<std::shared_ptr>();
std::unique_ptr<Base> uniqueBase = original.clone<std::unique_ptr>();
// the declarations below show it working through the base class for real
std::shared_ptr<Base> sharedBaseFromBase = sharedBase->clone<std::shared_ptr>();
std::unique_ptr<Base> uniqueBaseFromBase = uniqueBase->clone<std::unique_ptr>();
shared->speak();
unique->speak();
sharedBase->speak();
uniqueBase->speak();
sharedBaseFromBase->speak();
uniqueBaseFromBase->speak();
}
Compiles with gcc 4.8.1, and should in any compiler supporting variadics.
I would still prefer to simply return a unique_ptr and move the result into a shared_ptr, which would be automatic since the call to clone() is in itself an rvalue.
I have a class that takes nullable int as parameter.
public class Test
{
public Test(int? p)
{
// ......
}
// ......
}
How do I resolve it using unity (passing null as parameter)?
myContainer.RegisterType<Test>(new InjectionConstructor(10));
This works passing 10 as value, but if I pass null, it throws exception.
Edited to use generics:
Try to use InjectionParameter instead:
container.RegisterType<Test>(new InjectionConstructor(new InjectionParameter<int?>(null)));
Use an InjectionParameter<T> of the correct type, i.e.
container.RegisterType<Test>(new InjectionConstructor(new InjectionParameter<int?>(null)));
This has been tested in visual studio.
I've created a class that loads it's subclasses based on a name passed to it. The function uses getDefinitionByName, gets the class type, and instantiates it, and returns it if the class is a subtype of the class that owns this method. The subtypes are all mxml files that extend the base class, in order to simplify instantiating controls.
However, in the case where I pass it a fully qualified name, it works in my unit tests but fails when I execute it in the context of my application. Is there a gotcha in getDefinitionByName that makes it behave differently in different execution contexts? Is there a simpler way to load classes by their qualified name?
static public function loadDisplay(className:String, extendedClassName:String = null):FeatureDisplay
{
try
{
trace("Loading", className);
var cls:Class = getDefinitionByName(className) as Class;
var display:FeatureDisplay = new cls() as FeatureDisplay;
if(display)
{
return display;
}
else
{
trace(className, "is not a subclass of FeatureDisplay");
return null;
}
}
catch(error:Error)
{
trace("Error loading", className);
trace("Error:", error.message);
}
return null;
}
My first question is are you explicitly using any of the classes anywhere? If you do not actually use a class, even if it is imported, ActionScript may not end up keeping a copy of the class's definition in the swf.
That said, you're better off avoiding getDefinitionByName, describeType, getQualifiedClassName or getQualifiedSuperclassName if you can possibly avoid them. They are memory hogs and it is generally best to avoid them. (unless you do not have control over which classes will be used at run time and they HAVE to be used through getDefinitionByName).
My suggestion is that you replace getQualifiedClassName with a swtich...case:
// Import the subclasses.
import path.to.SpriteFeatureDisplay;
import path.to.OtherFeatureDisplay;
class FeatureDisplay extends Sprite{
//Make one public static const per class.
public static const SPRITE_FEATURE_DISPLAY:String = "sprite_feature_display";
public static const OTHER_FEATURE_DISPLAY:String = "other_feature_display";
public static function loadDisplay( className:String,
extName:String = null ):FeatureDisplay
{
trace("Loading", className);
// This will ensure that each of the classes is stored in the swf
// it will behave faster, and it is less prone to errors (note that
// try...catch is not needed).
swtich( className )
{
case SPRITE_FEATURE_DISPLAY:
return new SpriteFeatureDisplay();
case OTHER_FEATURE_DISPLAY:
return new OtherFeatureDisplay();
default:
trace( "Requested class " + className + " could not be created..." +
"\nPlease make sure that it is a subclass of FeatureDisplay" );
return null;
}
return null;
}
}
FYI, I've seen the following method of keeping classes used in Flex's source code:
// References.cs
// notice the double reference: one to import, the other to reference
import package.to.ClassA; ClassA;
import package.to.ClassB; ClassB;
import package.to.ClassC; ClassC;
Of course, you still have to reference the "References" class somewhere.