static_cast with unrelated classes - c++

I have following class structure:
Now I have a Device pointer, where I know that it is of type WiredHeadphone or RadioHeadphone. I need to cast this pointer to HeadphoneInterface.
In a perfect world I would just use a dynamic_cast. Unfortunately I am on an embedded platform which does not support dynamic_cast at all. Currently I do this:
HeadphoneInterface *GetDeviceAsHeadphone(Device* dev) {
// use my own type system to identify the actual type and cast accordingly:
if(dev->GetType() == Type_WiredHeadphone) {
return static_cast<HeadphoneInterface*>((WiredHeadphone *)dev);
} else if(dev->GetType() == Type_RadioHeadphone) {
return static_cast<HeadphoneInterface*>((RadioHeadphone *)dev);
} else {
return NULL;
}
}
This is ugly as hell and not maintainable. There will be more Headphone devices in the future, and I don't want to update this function every time.
Is there a better way to solve this?

You can add a virtual function to Device interface that does the (cross) cast to HeadphoneInterface for you:
struct HeadphoneInterface;
struct Device {
// ...
virtual HeadphoneInterface* getHeadphoneInterface() noexcept { return 0; }
// ...
};
And override the function in WiredHeadphone and RadioHeadphone to return a non-null pointer to HeadphoneInterface:
struct WiredHeadphone : WiredDevice, HeadphoneInterface {
HeadphoneInterface* getHeadphoneInterface() noexcept override { return this; }
};
Then GetDeviceAsHeadphone becomes:
inline HeadphoneInterface* GetDeviceAsHeadphone(Device* dev) noexcept {
return dev->getHeadphoneInterface();
}
Notice that no explicit cast is required here.

Related

Alternative to operator()() overloading? || Direct member access

I would like to wrap C types into a CPP class for better memory handling. For instance the below code snippet shows roughly what I would like to do:
class TJCompressor
{
public:
TJCompressor()
: m_tjInstance(tjInitCompress())
{
if (m_tjInstance == nullptr)
throw std::runtime_error("Could not create a TJ compressor instance");
}
~TJInstance()
{
tjDestroy(m_tjInstance);
}
const tjhandle& operator()() const
{
return m_tjInstance;
}
private:
tjhandle m_tjInstance = nullptr;
};
However, now I need to access the actual tjhandle through operator()() and I would prefer to get rid of this.
TJCompressor compressor;
tjDecompressHeader3(decompressor(), ... ); // works as expected
tjDecompressHeader3(decompressor, ... ); // preferred way of doing it
I am pretty sure that this is achievable but I somehow can't find anything about how to do it.
What you want I think is a conversion operator .... something that looks like
operator const tjhandle & () const { return m_tjInstance; }
you will then be able to call your function as
tjDecompressHeader3(decompressor, ...)
More information can be found here:
https://en.cppreference.com/w/cpp/language/cast_operator

Is it possible to change behavior of function based on scope?

I would like to create something similar to rust unsafe scope in C++.
The idea is that I have some functions performing number of checks. For example:
void check() {
if (...)
throw exception(...);
}
void foo() {
check();
// do some work
}
Now, I want to be able to call function foo() with or (in different context) without performing those checks. Ideally it would look like this:
foo(); // call foo and perform checks
unsafe {
foo(); // call foo without checks
}
My question is, is it possible to achieve something like this in compile time? Is it possible to somehow check (or act differently) from check function in what scope it is called?
I came up only with a runtime solution: to wrap it in some lambda:
unsafe([&] {
foo();
});
where unsafe is implemented as follows:
void unsafe(std::function<void()> f)
{
thread_local_flag = unsafe;
f();
thread_local_flag = safe;
}
check() function would just check for the thread_local flag and perform checks only when it is set to safe.
🤔
namespace detail_unsafe {
thread_local int current_depth;
struct unsafe_guard {
unsafe_guard() { ++current_depth; }
~unsafe_guard() { --current_depth; }
unsafe_guard(unsafe_guard const &) = delete;
unsafe_guard &operator = (unsafe_guard const &) = delete;
};
}
#define unsafe \
if(::detail_unsafe::unsafe_guard _ug; false) {} else
bool currently_unsafe() {
return detail_unsafe::current_depth > 0;
}
See it live on Coliru. Also, please don't actually define unsafe as a macro...
is it possible to achieve something like this in compile time?
Not the way you presented. Making foo a template function might give you equivalent results, though:
enum class CallType // find a better name yourself...
{
SAFE,
UNSAFE,
};
template <CallType Type = CallType::SAFE>
void foo()
{
if constexpr(Type != CallType::UNSAFE)
{
if (...)
throw ...;
}
// do some work
}
You might call it like:
foo();
foo<CallType::UNSAFE>();
Disliking templates?
Simple approach (thanks, #VTT):
void check(); // no template any more
void foo_unsafe()
{
// do some work
}
inline void foo()
{
check();
foo_unsafe();
}
Or selecting via parameter (this pattern exists in standard library, too):
struct Unsafe
{
};
inline Unsafe unsafe;
void check();
void foo(Unsafe)
{
// do some work
}
inline void foo()
{
check();
foo(unsafe);
}
Edit:
Well, in the example I presented I could do that, but in general, I can call some other function bar inside unsafe which in turn calls foo. And I don't want to specialize bar and possible other methods.
Unter this constraint, the template variant might be the closest you can get to at compile time; you don't have to specialise all the functions, but you'd need to make templates from:
template <CallType Type = CallType::SAFE>
void bar()
{
// do some other work
foo<Type>(); // just call with template parameter
// yet some further work
}
I would simply use a RAII type to toggle the unsafe flag inside a scope as such:
thread_local bool unsafe_flag = false;
/// RAII Type that toggles the flag on while it's alive
/// Possibly add a reference counter so it can be used nested
struct unsafe_scope
{
constexpr unsafe_scope() { unsafe_flag = true; }
~unsafe_scope() { unsafe_flag = false; }
};
/// Gets a value from a pointer
int get_value(int* ptr)
{
if ( unsafe_flag )
{
if ( ptr == nullptr ) { return 0; }
}
return *ptr;
}
int main()
{
int* x = nullptr;
//return get_value(x); // Doesn't perform the check
{
unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
}
In order to make it nested I would add a reference counter like this:
/// RAII Type that toggles the flag on while it's alive
struct unsafe_scope
{
thread_local static size_t ref_count;
constexpr unsafe_scope()
{
unsafe_flag = true;
ref_count++;
}
~unsafe_scope()
{
ref_count--;
if ( ref_count == 0 ) { unsafe_flag = false; }
}
};
/// In source file
thread_local size_t unsafe_scope::ref_count = 0;
The ref_count doesn't need to be atomic since it's thread_local
Now I don't think there's a way to achieve the syntax you wanted with the unsafe before the scope, but if you put it right after the scope as such it should be about the same:
{ unsafe_scope cur_scope;
return get_value(x); // Performs the check
}
Edit:
I've now noticed Quentin's answer is also a RAII type, just with slightly different semantics, instead of having a global thread_local flag a function just returns if the reference counter is bigger than 0. Also the macro achieves the exact syntax you wanted, although it's also possible with this unsafe_scope by modifying his macro like this:
#define unsafe\
if (unsafe_scope cur_scope; false) {} else
His method uses C++17's if initializer, which lets you initiates a variable in the if statement, but the variable is still initialized in the else block, so it only gets destroyed after the else scope if over.

Inheritance and pointers

I have code like this:
class Human
{
protected:
int age;
std::string sex;
public:
virtual void speak() = 0;
};
class Child:public Human
{
public:
void speak(){std::cout << "I am Child\n";}
};
class Man:public Human
{
public:
void speak(){std::cout << "I am Man\n";}
};
class Woman:public Human
{
public:
void speak(){std::cout << "I am Woman\n";}
};
(don't know, std::shared_ptr<Human> maybe?) operator*(std::shared_ptr<Child> &b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man")
{
return (i want b to become std::shared_ptr<Man>)
}
if(b->getAge()>18 && b->getSex()=="Woman")
{
return (here I want b to become std::shared_ptr<Woman>);
}
return;
}
int main(){
auto x = std::make_shared<Child>;
x*19;
}
I know it seems odd, but it's the simplest case i can think of, without having to write down all code i'm struggling with rn. Could someone explain, what type should overload be and how to change shared_ptr type, knowing they derive from same parent?
Objects cannot change type. A Child object will always be a Child object. What you can do is create a new object with the properties you want and return that:
std::shared_ptr<Human> operator*(std::shared_ptr<Human> b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man") {
return std::make_shared<Man>(b->getAge());
} else if(b->getAge()>18 && b->getSex()=="Woman") {
return std::make_shared<Woman>(b->getAge());
} else {
return b;
}
}
int main(){
std::shared_ptr<Human> x = std::make_shared<Child>;
x = x*19;
}
This doesn't seem like a good design though. A Human's status as a child or adult would be better represented as an attribute of the object or by a function that checks if age is greater than 18.
You cannot make the type T<Derived> inherit from T<Base> because C++ templates do not support covariance. To do so would be unsafe for certain types, such as mutable references to containers. (Imagine taking a reference to std::vector<Cat> as std::vector<Animal>& and pushing back a dog!)
(I would make this answer a comment, but I don't have comment abilities.)
Update:
You can write a non-template wrapper that handles heap data:
class Wrapper
{
public:
Wrapper(Base* b) : raw(b) {}
~Wrapper() { delete raw; }
Base& get() { return *base; }
private:
Base* raw;
}
Of course, in your example, you use std::shared_ptr and not std::unique_ptr. You would have to handle reference counting instead of simply deleting the data in the destructor, but the technique of keeping an internal raw pointer still stands.
Update 2:
The above code could be used as is to provide a level of indirection, such that all classes that inherit from the base class may be held in the same type, without writing your own reference counter:
std::shared_ptr<Wrapper>
This solution may be seen as similar to doing std::shared_ptr<Base*>, except that the latter solution would leak memory.

Determine if a type is Nullable and get the base type?

Let's say I have this function template:
void bar(T)(T obj) {
// ...
}
I'd like to change the behavior of the function if T is some Nullable!U, so that if obj.isNull is true, I do some alternate flow, or otherwise continue as if a plain U type had been passed instead.
void bar(T)(T obj) {
static if(is(T == Nullable!U)) { // ?
if(obj.isNull) {
writeln("Object was null!");
return;
}
auto realObj = obj.get;
} else {
alias realObj = obj;
}
writeln("Object was "~to!string(realObj));
}
Is there a way to check if T is an instance of Nullable, and if so, get the wrapped type?
Or more generally, is there a way to check if type T is an instantiation of some template Foo, and get the template parameters if so?
You can provide a specific overload for Nullables:
void bar(T : Nullable!U, U)(T obj) {
if (obj.isNull) {
writeln("Object was null!");
return;
}
bar(obj.get);
}
void bar(T)(T obj) {
writeln("Object was "~to!string(obj));
}
Your code is mostly correct, all you need is to change this line:
static if(is(T == Nullable!U))
to this
static if(is(T == Nullable!U, U)), and U will be aliased to the type of the Nullable (i.e. int, ...)
Code: http://dpaste.dzfl.pl/cc225c8d4ca3

What is the right way to switch on the actual type of an object?

I'm writing an xml parser and I need to add objects to a class generically, switching on the actual type of the object. Problem is, I'd like to keep to an interface which is simply addElement(BaseClass*) then place the object correctly.
void E_TableType::addElement(Element *e)
{
QString label = e->getName();
if (label == "state") {
state = qobject_cast<E_TableEvent*>(e);
}
else if (label == "showPaytable") {
showPaytable = qobject_cast<E_VisibleType*>(e);
}
else if (label == "sessionTip") {
sessionTip = qobject_cast<E_SessionTip*>(e);
}
else if (label == "logoffmedia") {
logoffMedia = qobject_cast<E_UrlType*>(e);
}
else {
this->errorMessage(e);
}
}
This is the calling class, an object factory. myElement is an instance of E_TableType.
F_TableTypeFactory::F_TableTypeFactory()
{
this->myElement = myTable = 0;
}
void F_TableTypeFactory::start(QString qname)
{
this->myElement = myTable = new E_TableType(qname);
}
void F_TableTypeFactory::fill(const QString& string)
{
// don't fill complex types.
}
void F_TableTypeFactory::addChild(Element* child)
{
myTable->addElement(child);
}
Element* F_TableTypeFactory::finish()
{
return myElement;
}
void F_TableTypeFactory::addAttributes(const QXmlAttributes &attribs) {
QString tName = attribs.value(QString("id"));
myTable->setTableName(tName);
}
Have you considered using polymorphism here? If a common interface can be implemented by each of your concrete classes then all of this code goes away and things become simple and easy to change in the future. For example:
class Camera {
public:
virtual void Init() = 0;
virtual void TakeSnapshot() = 0;
}
class KodakCamera : Camera {
public:
void Init() { /* initialize a Kodak camera */ };
void TakeSnapshot() { std::cout << "Kodak snapshot"; }
}
class SonyCamera : Camera {
public:
void Init() { /* initialize a Sony camera */ };
void TakeSnapshot() { std::cout << "Sony snapshot"; }
}
So, let's assume we have a system which contains a hardware device, in this case, a camera. Each device requires different logic to take a picture, but the code has to support a system with any supported camera, so we don't want switch statements littered throughout our code. So, we have created an abstract class Camera.
Each concrete class (i.e., SonyCamera, KodakCamera) implementation will incluse different headers, link to different libraries, etc., but they all share a common interface; we just have to decide which one to create up front. So...
std::unique_ptr<Camera> InitCamera(CameraType type) {
std::unique_ptr<Camera> ret;
Camera *cam;
switch(type) {
case Kodak:
cam = new KodakCamera();
break;
case Sony:
cam = new SonyCamera();
break;
default:
// throw an error, whatever
return;
}
ret.reset(cam);
ret->Init();
return ret;
}
int main(...) {
// get system camera type
std::unique_ptr<Camera> cam = InitCamera(cameraType);
// now we can call cam->TakeSnapshot
// and know that the correct version will be called.
}
So now we have a concrete instance that implements Camera. We can call TakeSnapshot without checking for the correct type anywhere in code because it doesn't matter; we know the correct version for the correct hardware will be called. Hope this helped.
Per your comment below:
I've been trying to use polymorphism, but I think the elements differ too much. For example, E_SessionTip has an amount and status element where E_Url just has a url. I could unify this under a property system but then I lose all the nice typing entirely. If you know of a way this can work though, I'm open to suggestions.
I would propose passing the responsibility for writing the XML data to your types which share a common interface. For example, instead of something like this:
void WriteXml(Entity *entity) {
switch(/* type of entity */) {
// get data from entity depending
// on its type and format
}
// write data to XML
}
Do something like this:
class SomeEntity : EntityBase {
public:
void WriteToXml(XmlStream &stream) {
// write xml to the data stream.
// the entity knows how to do this,
// you don't have to worry about what data
// there is to be written from the outside
}
private:
// your internal data
}
void WriteXml(Entity *entity) {
XmlStream str = GetStream();
entity->WriteToXml(stream);
}
Does that work for you? I've done exactly this before and it worked for me. Let me know.
Double-dispatch may be of interest. The table (in your case) would call a virtual method of the base element, which in turns calls back into the table. This second call is made with the dynamic type of the object, so the appropriate overloaded method is found in the Table class.
#include <iostream>
class Table; //forward declare
class BaseElement
{
public:
virtual void addTo(Table* t);
};
class DerivedElement1 : public BaseElement
{
virtual void addTo(Table* t);
};
class DerivedElement2 : public BaseElement
{
virtual void addTo(Table* t);
};
class Table
{
public:
void addElement(BaseElement* e){ e->addTo(this); }
void addSpecific(DerivedElement1* e){ std::cout<<"D1"; }
void addSpecific(DerivedElement2* e){ std::cout<<"D2"; }
void addSpecific(BaseElement* e){ std::cout<<"B"; }
};
void BaseElement::addTo(Table* t){ t->addSpecific(this); }
void DerivedElement1::addTo(Table* t){ t->addSpecific(this); }
void DerivedElement2::addTo(Table* t){ t->addSpecific(this); }
int main()
{
Table t;
DerivedElement1 d1;
DerivedElement2 d2;
BaseElement b;
t.addElement(&d1);
t.addElement(&d2);
t.addElement(&b);
}
output: D1D2B
Have a Look at the Visitor Pattern, it might help you