Why use static_cast for auto pointer in C++11? - c++11

I saw that cocos2dx (v3) example :
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Why not use dynamic_cast()? It is not static variable.

static_cast() has nothing to do with static specifier. If performs the cast during compile time (i.e. "statically"), which was possible in case of the code you have added to your question.
On the other side, dynamic_cast() is performed during runtime.

Related

Making a template function work with both lvalue and rvalues pointer arguments

I currently have a memory leak in my project. To resolve the memory leak, I am trying to replace the pointers into std:: unique_ptr. The pointer to the heap is not from my project, but rather from a library called Xerces(an XML parsing library).
In this library, it can transcodes char * to XMLCh * in both ways.
So in real code, it comes like ..
XMLCh * xmlstr = XMLString::transcode("abc",...);
char * charstr = XMLString::transcode(xmlstr,...);
since both methods allocates heap area and returns the pointer for it, I should explicitly call
XMLString::release(xmlstr);
XMLString::release(charstr);
after using it to clean up. I want to write a custom deleter for two types (char * and XMLCh *) using std::unique_ptr.
The release method has a type of
XMLString::release(char **str);
XMLString::release(XMLCh **str);
It is using double pointer because it sets the pointer to null after release.
I thought to make the template accept reference pointers like this,
template<typename T>
void release(T *& ptr){
XMLString::release(ptr);
}
but just realized that it will be possible to
XMLCh * xmlstr = XMLString::transcode("abc",...);
auto uptr = unique_ptr<XMLCH, decltype(&release<T>)>(xmlstr)
do this, but not possible to
auto xmluptr = unique_ptr<XMLCH, decltype(&release<T>)>(XMLString::transcode("abc",...));
do something like this, because it is accepting a rvalue in the parameter but the argument is a reference pointer. Is it possible to instantiate both cases writing only one template function?
By the way, I am using c++11.
So if I understand correctly, your problem is that XMLString::release takes a pointer-to-point and it does not fit into the unique_ptr release function. Well, the correct solution is to wrap it like
template<typename T>
void release(T *ptr){
XMLString::release(&ptr);
}
The XMLString::release will only null-out the copy of the pointer inside the wrapper, but since the unique_ptr takes care of rendering itself unusable itself, you don't need that functionality of XMLString::release.
In either case, the type of the release wrapper does not affect how the unique_ptr is constructed, because the release wrapper will be called with the internal member of the unique_ptr as argument. So either unique_ptr accepts that argument, and both assignments will work, or unique_ptr won't accept it and neither will.
That said, the point of unique_ptr is that you wrap the pointer in it immediately when you get it. So don't store it in variable before.

Arguments/Struct compatibility when calling a dynamic library on OSX

I have 2 separate projects on OSX:
-the first is a MachO Dynamic Library project in XCode.
It has a function that is being called with an argument (a struct).
-the second is a Qt application project in Qt Creator.
It loads the dynamic library and calls the function, passing a struct as an argument.
Of course both share the same declaration of that function and struct.
The problem is, when I call the function, the values in the struct received in the function have nothing to do with the values I sent from the application. A simple printf before calling the function and another one within the function shows completely different values.
What did I did wrong?
My struct is composed of the following elements :
-multiple std::string
-multiple int
-multiple char[64]
Thanks!
The problem was an incompatibility with std::string, something about compiler flags/library that change the way std::string are implemented. I just changed everything to char[].

Is it valid to return a unique_ptr pointing to a forward declared class?

Following code does not compile with clang-700.1.81 and it's standard library:
#include <memory>
class something;
std::unique_ptr<something> external_function();
std::unique_ptr<something> local_function()
{
auto thing = external_function();
return thing;
}
The diagnostics by clang:
......./include/c++/v1/memory:2626:46: note: in instantiation of member function 'std::__1::unique_ptr.....requested here
_LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
^
test.cc:10:18: note: in instantiation of member function 'std::__1::unique_ptr<something, std::__1::default_delete<something> >::~unique_ptr' requested here
auto thing = external_function();
^
test.cc:4:7: note: forward declaration of 'something'
class something;
^
I guess it is trying to destroy the unique_ptr after copying it as return value, but is this really necessary? It is going be moved anyways, does it need to check if it can copy before realizing that it is easier to move it?
I could of course do this easily with a naked pointer.
Is there some other way to allow a uniqe_ptr to just "pass through" a translation unit, as shown in the example, without including extra header to get the definition of class something?
------EDIT--------
Also tried with GCC 5.3.0 and gnu libstdc++
Does not compile as well, with similar error messages.
------EDIT----
I think it is just trying to destroy the original thing object.
Thanks to Rudolf for the deleter idea ( a bit messy, but only option for this )
Looking at the library code I found this in unique_ptr's code:
if (__tmp)
__ptr_.second()(__tmp);
where second(_tmp) destructs the object pointed to. Even though it is never called, the compiler needs a definition to compile it. This is silly, but apparently gotta live with it.
From cppreference.com:
std::unique_ptr may be constructed for an incomplete type T, such as to facilitate the use as a handle in the Pimpl idiom. If the default deleter is used, T must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function of std::unique_ptr. (Conversely, std::shared_ptr can't be constructed from a raw pointer to incomplete type, but can be destroyed where T is incomplete).
Thus, with a custom deleter you can use a forward declared class if the full declaration is available for the deleter:
#include <memory>
class Foo;
class FooDeleter
{
public:
void operator()(Foo* pInstance);
};
std::unique_ptr<Foo, FooDeleter> pFoo;
class Foo
{
};
void FooDeleter::operator()(Foo* pInstance)
{
delete pInstance;
}

Is there any way to make the DialogProc work without declaring as Nonstatic

I have developed any button application using createDialogParam and DialogProc. first i declared DialoProc method as static in order to make every thing work fine and it worked but now the situation is that there are so many variables(Not globally declared) and functions which i have to use inside DialogProc function and now i want to make it Non static because making it static makes me not implement few more things.
If i don't declare it static it gives error
m_hwndPreview = CreateDialogParam( g_hInst,MAKEINTRESOURCE(IDD_MAINDIALOG), m_hwndParent,(DLGPROC)DialogProc, (LPARAM)this); //('type cast' cannot convert from 'overloaded-function'
//to 'DLGPROC')
Is there any solution to make dialogProc function without declaring it static ???
It must be a static function because Windows calls it from C code, not C++ code. But there are several ways your static function can retrieve a 'this' pointer that you saved somewhere, then use that pointer to call a class member function. Every GUI library available for Windows solves this problem: Consider using one.

Calling a property on the const reference

I have C++/CLI class that defines a property:
public ref class AbstractOffer
{
public:
AbstractOffer();
property String^ Body;
};
In some function the AbstractOffer class is passed by const ref
foo(const AbstractOffer^ ao)
{
ao->Body;
}
When I call the property the method compiler gives the following error :-
error C2662: 'ivrworx::interop::AbstractOffer::Body::get' : cannot
convert 'this' pointer from 'const ivrworx::interop::AbstractOffer'
to 'ivrworx::interop::AbstractOffer %' 1> Conversion loses
qualifiers
It seems somehow connected to const. How can I call the Body property of the object if the object reference is passed by const?
The const qualifier is a problem in C++/CLI. It is only meaningful when it can be checked and that's not in general possible in .NET. It is of course not a problem when you only have one kind of compiler and that compiler follows strict language rules. Like C++. But .NET supports many languages, your method could be easily called from a Cobol.NET program for example. The odds of ever getting const-correctness added to the Cobol language are zero.
The compiler does compile code with const qualifiers and does make an effort to check when it can. Which is why you got the diagnostic. That can even work when the declaration exists in another assembly, as long as it was compiled with C++/CLI, the compiler emits modopt annotations in the metadata.
But there are limitations with that. Properties are one of them, you can't add the const qualifier to the getter, or a member function in general, you'll get slapped with C3842.
Best thing to do is to use C++/CLI for what it is good at, it is an interop language. And const qualifiers just don't work well in an interop scenario.
The only way I know to get round this is the cast away the const-ness. As long as you don't modify the object, it should be fine. (If you do modify it, I've no idea what the outcome will be).
i.e. change your function to be
void foo(const AbstractOffer^ ao)
{
const_cast<AbstractOffer^>(ao)->Body;
}

Resources