mardi 26 juin 2018

Derived classes from abstract base class

I am trying to use a derived class from an abstract base class in c++ (c++11). I can not post exact code but here is an example of my implementation:

class A{
    protected:
        union x {
          struct type_a{
              uint8_t data : 8;
          };
          struct type_b{
              uint8_t data : 12;
          }; 
        };
    public:
        virtual int get_word() = 0; //pure virtual, makes class abstract
};

class B : public A{
    private:
        struct type_var{}type; //used to store struct type from base class
    public:
        B(int select) {
            switch(select) {
                case CNTR_GRP:
                   type = x.type_a; //error here
                break;
                /*... more similar case statements */
        }
        //implement get_word().. etc
};

Now like I said, I can only show example code. I need the derived class to select the correct struct type from the base (abstract) class. The type of the struct is not known until runtime so this is why it is structured like so. My current error is error: expected primary-expression before ‘.’ token which occurs where I commented. I have tried many different ways of accessing and setting the proper struct from base class such as type = A::x.type_a; but have failed to get it to work.

I have researched and read lots of posts on SO and tried following implementations and examples but can't get it to work. Am I missing something here? Thanks for the help, hopefully I'm not missing something completely obvious.

Resources I have used:

Interfaces in C++ (Abstract Classes)

How to access protected members in derived class?

Why does a purely virtual/abstract class require a constructor, in particular for protected const member variables?

  • several more that I closed and can't seem to find.

Why I get the following error: "returning reference to temporary [-Werror=return-local-addr]"

given the following code:

#include <set>

using std::set;

class Pool {
    set<int> s;
public:
    Pool();
    ~Pool();

    typedef typename set<int>::iterator Iterator;
    const Iterator& begin() const;
    // Iterator& begin();
    // const Iterator& end() const;
    // Iterator& end();
};

Pool::Pool() = default;
Pool::~Pool() = default;

const typename Pool::Iterator& Pool::begin() const {
    return s.begin(); //** error
}

Why I get the following error (I understand the meaning of the error, but, I don't understand why I get it in this case)?

returning reference to temporary [-Werror=return-local-addr]

How can I fix it?

How to make the default destructor non-inline?

How can one force the compiler to make the default destructor of a class non-inline?

One way of doing this is to write an empty destructor definition, but it feels messy and also you get a warning from the static analyzer (clang-tidy in my case), that = default should be used for a trivial destructor.

To elaborate more on the actual use case - the goal is to have something similar to:

MyClass.h

class MyClassImpl;

class MyClass {
    std::unique_ptr<MyClassImpl> m_impl;
public:
    MyClass();
    // and some other methods
};

A std::unique_pointer to an incomplete type, which is forward declared in the header and the definition is known only in the source file.

The code above will give a compiler error:

error: use of undefined type 'MyClassImpl'

The actual problem is, that the default destructor of MyClass generated by the compiler is inline and so it needs the complete type info of MyClassImpl.

This can be fixed by adding an empty destructor for MyClass (by declaring in the header and defining in the source file, since defining in the header will implicitly make it inline which will cause the same error).

But is this the only way in modern C++?

time complexity of find fun in vector stl c++

Can you explain how find function works in STL C++ vector and what is its time complexity?

vector<int> v; if(find(v.begin(),v.end(),element)==v.end()) do this; else do this

Inserting multiple not-a-numbers into a std::unordered_set

One of consequences of the IEEE 754 standard is the non-intuitive behavior of std::unordered_set<double>, when not-a-number elements (NANs) are inserted.

Due to the fact that NAN!=NAN, after the following sequence:

#include <iostream>
#include <cmath>
#include <unordered_set>

int main(){
    std::unordered_set<double> set;
    set.insert(NAN);
    set.insert(NAN);
    std::cout<<"Number of elements "<<set.size()<<"\n";  //there are 2 elements!
}

there are two elements in the set(see it live): NAN and NAN!

Mine main issue with this is, that when N NANs are inserted into the hash-set, they all hit the same hash-bucket and the performance of N inserts into the hash-set degenerates to the worst-case running time - O(N^2).

For an example, see the listing at the end of the question or here live - inserting NAN takes some order of magnitude more time than a "normal" floating number.

My question: is it possible (and if yes - how) to tweak std::unordered_set<double> in such a way, that there is at most one NAN-element in the set, no matter the flavor of inserted NANs (NAN, -NAN and so on)?


Listing:

#include <iostream>
#include <cmath>
#include <unordered_set>
#include <chrono>

constexpr int N=5000;
void test_insert(double value)
{
    std::unordered_set<double> s;
    auto begin = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < N; i++) {
        s.insert(value);
    }
    auto end = std::chrono::high_resolution_clock::now();
    std::cout << "Duration: " << (std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count() / 1e9) << "\n";
    std::cout << "Number of elements: "<<s.size()<<"\n";
}

int main(){
    std::cout << "Not NAN\n";
    test_insert(1.0);           //takes 0.0001 s
    std::cout << "NAN\n";
    test_insert(NAN);           //takes 0.2 s
}

How can I fix it "Member declaration not found"?

given the following code:

template<class T>
class Point {
    T x;
    T y;
public:
    Point(T x, T y);

    Point(const Point& p);
    ~Point();
    Point& operator=(const Point& p);

    Point& operator+=(const Point& Prhs);
};

template<class T>
Point<T>& Point<T>::operator+=(const Point<T>& Prhs) {//**error1**
    this->x += Prhs.x; //**error2**
    this->y += Prhs.y; //**error3**
    return *this;
}

template<class T>
Point<T> operator+(const Point<T>& Plhs, const Point<T>& Prhs) { 
    return Plhs += Prhs;
}  

I get the following errors:

error1: Member declaration not found

error2: Field 'x' could not be resolved

error3: Field 'y' could not be resolved

I don't understand what is the reason of these errors. How can I fix it?

Is it possible to show an application without its dock icon on Mac dinamically?

I am working on an application using Qt and C++. I have 2 windows: one main window and one floating window. I must have an option in the app to toggle the dock icon on or off, but when the floating window is visible I must leave the dock icon there.