How to access virtual functions using vtable? - c++11

So I'm trying to access the virtual functions values using vtable. The way I understand it is that the compiler creates a pointer to the vtable, and a vtable is created for each class that contains a virtual function. I was able to get the values for the first two members. Now I don't understand how go about getting the values for 'bar' function.
#include <cstdio>
#include <iostream>
class Thing
{
private:
int x;
int y;
virtual int foo()
{
return x+y;
}
virtual int bar()
{
return x*y;
}
public:
Thing(){
x = 2;
y = 10;
}
};
int extract_x(void *thing)
{
// --- Begin your code ---
char* ptrA = (char*)thing;
ptrA=ptrA+8;
return *ptrA;
return 0;
// --- End your code ---
}
int call_bar(void* thing)
{
// --- Begin your code ---
// --- End your code ---
return 0;
}
int main()
{
Thing thing;
std::printf("%d %d\n",
extract_x(&thing),
call_bar(&thing));
return 0;
}

What you're trying to do is either unsupported/undefined, or if it is defined - quite imprudent. If A is a base class of B, and you believe your A* ptr is actually a B*, just use dynamic_cast<B*>(ptr) and access the B methods like a civilized human being... (but check the result the cast for being nullptr, in case it wasn't a B* after all.)

Related

Accessing Base class variable inside Derived class

I have a public inheritance, Derived struct inheriting from Base. The Base has a data member int i initialized to 5.
Now I have two codes.
Code 1 : Compiles fine
#include <iostream>
using namespace std;
struct Base{
int i = 5;
};
struct Derived: public Base{
int j = i; // Derived class able to use variable i from Base
Derived(){
i = 10; // Constructor of Derived able to access i from Base
}
};
int main()
{
Derived dobj;
cout << dobj.i;
return 0;
}
Code 2 : Gives error
#include <iostream>
using namespace std;
struct Base{
int i = 5;
};
struct Derived: public Base{
int j = i; //Still works
i = 10; // Error here " main.cpp:15:3: error: ā€˜iā€™ does not name a type"
Derived() = default;
};
int main()
{
Derived dobj;
cout<<dobj.i;
return 0;
}
Why is it that i can be used to assign and be assigned inside constructor body (as in code 1), but not used directly in Derived class (as in code 2). Also what does the error mean?
I was under the impression that the scope of Derived is nested inside Base, so shouldn't it be able to see the data members inside Base scope?
This has nothing to do with base and derived classes but with scope. Your code is illegal for the same reason that this code is illegal:
struct X
{
int i;
i = 20; // error
};
https://godbolt.org/z/60zPb-
int i; or int i = 10; are declarations. i = 20; is a statement. Statements can only appear in function bodies, not at class (or namespace) scope.

Can a method of an class (in a shared_ptr) be tied to a static function in a traits class?

Historically, I've been using trait classes to hold information and apply that into a "generic" function that runs the same "algorithm." Only differed by the trait class. For example: https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
I'm not sure how to create "generic" algorithms this when dealing with polymorphic classes.
For example: https://onlinegdb.com/S1hFLGC7V
Below I have created an inherited class hierarchy. In this example I have a base catch-all example that defaults all the parameters to something (0 in this case). And then each derived class sets overrides specific methods.
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
Here I created a simple factory, not elegant but for illustrative purposes
// example simple factory
std::shared_ptr<Base> get_class(const int input) {
switch(input)
{
case 0:
return std::shared_ptr<Base>(std::make_shared<A>());
break;
case 1:
return std::shared_ptr<Base>(std::make_shared<B>());
break;
default:
assert(false);
break;
}
}
So this is the class of interest. It is a class does "something" with the data from the classes above. The methods below are a simple addition example but imagine a more complicated algorithm that is very similar for every method.
// class that uses the shared_ptr
class setter {
private:
std::shared_ptr<Base> l_ptr;
public:
setter(const std::shared_ptr<Base>& input):l_ptr(input)
{}
int get_thing_a()
{
return l_ptr->get_thing_one() + l_ptr->get_thing_two();
}
int get_thing_b()
{
return l_ptr->get_thing_three() + l_ptr->get_thing_four();
}
};
int main()
{
constexpr int select = 0;
std::shared_ptr<Base> example = get_class(select);
setter l_setter(example);
std::cout << l_setter.get_thing_a() << std::endl;
std::cout << l_setter.get_thing_b() << std::endl;
return 0;
}
How can I make the "boilerplate" inside the setter class more generic? I can't use traits as I did in the example above because I can't tie static functions with an object. So is there a way to make the boilerplate example more common?
Somewhere along the lines of having a selector, say
enum thing_select { THINGA, THINGB, };
template < thing_select T >
struct thing_traits;
template <>
struct thing_traits<THINGA>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_one' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_two' method
}
template <>
struct thing_traits<THINGB>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_three' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_four' method
}
// generic function I'd like to create
template < thing_select T, typename TT = thing_traits<T> >
int perform_action(...)
{
return TT::first_function(..) + TT::second_function(..);
}
I ideally would like to modify the class above to something along the lines of
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
The answer is, maybe I can't, and I need to pass int the shared_ptr as a parameter and call the specific methods I need instead of trying to tie a shared_ptr method to a static function (in hindsight, that doesn't sound like a good idea...but I wanted to bounce my idea)
Whoever makes the actual call will need a reference of the object, one way or the other. Therefore, assuming you want perform_action to perform the actual call, you will have to pass the parameter.
Now, if you really want to store which function of Base to call as a static in thing_traits without passing a parameter, you can leverage pointer to member functions:
template <>
struct thing_traits<THINGA>
{
static constexpr int (Base::*first_function)() = &Base::get_thing_one;
...
}
template < thing_select T, typename TT = thing_traits<T>>
int perform_action(Base & b)
{
return (b.*TT::first_function)() + ...;
}
You can also play instead with returning a function object that does the call for you (and the inner function takes the parameter).
It all depends on who you need to make the call and what information/dependencies you assume you have available in each class/template.

C++ pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

I keep getting this error. I know what function causes it, but don't know how to fix it. Looking up online from this post saying:
You need to pass a pointer to a dynamically allocated object, or make your own insde your chainLink class.
However, as I try to pass a string pointer. error still popping up. Here is my code.
#include <iostream>
#include "MWTNode.h"
#include "MWT.h"
using namespace std;
int main() {
MWT t;
string str ="abc";
string* strPtr = &str;
t.insert(strPtr);
std::cout << "Hello, World!" << std::endl;
return 0;
}
#include "MWTNode.h"
class MWT {
public:
MWTNode *root;
string find(const string &);
void insert(const string* string);
};
void MWT::insert(const string* word) {
MWTNode* curr = root;
MWTNode newNode;
string w = *word;
for (int i = 0; i < word->length(); i++) {
const char c = w[i];
if (curr->children.find(c) == curr->children.end()){
//curr->children[c]= MWTNode();
//node->frequency=node->frequency+1;
}
curr = &(curr->children[c]);
}
curr->flag = true;
}
#include <unordered_map>
#include <vector>
#include <string>
#include <sstream>
#include <set>
using namespace std;
class MWTNode {
public:
unordered_map<char, MWTNode> children;
string value;
bool flag;
int frequency;
MWTNode(const string &);
MWTNode(const char c);
MWTNode();
void setFrequency ();
int getFrequency ();
};
MWTNode::MWTNode(const string &val) {
value = val;
flag = false;
frequency = 0;
}
MWTNode::MWTNode(const char c) {
value =c;
flag = false;
frequency = 0;
}
MWTNode::MWTNode() {
value ="";
flag = false;
frequency = 0;
}
Lets highlight a few lines of the code you show
class MWT {
public:
MWTNode *root;
// ...
};
In that you declare the member variable root as a pointer.
void MWT::insert(const string* word) {
MWTNode* curr = root;
// ...
}
In the above you make curr point to where root is pointing.
But you never make root point anywhere! The MWT::root variable is uninitialized and will have an indeterminate value. Using this pointer in any way without initialization will lead to undefined behavior.
And yes you use this pointer, as you dereference curr inside the MWT::insert function.
It's a little unclear what you're doing (to me) but you need to make sure that root (and therefore curr) is a valid pointer before attempting to dereference it.

Is it possible to have a copy constructible class that holds a std::unique_ptr<Base> avoiding slicing without Base exposing a "clone" function?

Is there a way to write a copy-constructor for a class (say, Copyable, that holds a std::unique_ptr to a Base class (but really is storing Derived objects.
A quick test shows the expected slicing occurs, because Copyable doesn't know the real type it's holding. So I suppose a clone method is needed, but I'm wondering if there is a way to let the compiler handle this in some better way?
The slicing code:
#include <algorithm>
#include <iostream>
#include <memory>
struct Base
{
Base(int i = 0) : i(i) {}
virtual ~Base() = default;
int i;
virtual int f() { return i; }
};
struct Derived : Base
{
Derived() = default;
virtual int f() override { return 42; }
};
struct Copyable
{
Copyable(std::unique_ptr<Base>&& base) : data(std::move(base)) {}
Copyable(const Copyable& other)
{
data = std::make_unique<Base>(*other.data);
}
std::unique_ptr<Base> data;
};
int main()
{
Copyable c(std::make_unique<Derived>());
Copyable c_copy = c;
std::cout << c_copy.data->f() << '\n';
}
The clone code:
#include <algorithm>
#include <iostream>
#include <memory>
struct Base
{
Base(int i = 0) : i(i) {}
virtual ~Base() = default;
int i;
virtual int f() { return i; }
virtual Base* clone() { return new Base(i); }
};
struct Derived : Base
{
Derived() = default;
virtual int f() override { return 42; }
virtual Derived* clone() override { return new Derived(); }
};
struct Copyable
{
Copyable(std::unique_ptr<Base>&& base) : data(std::move(base)) {}
Copyable(const Copyable& other)
{
data.reset(other.data->clone());
}
std::unique_ptr<Base> data;
};
int main()
{
Copyable c(std::make_unique<Derived>());
Copyable c_copy = c;
std::cout << c_copy.data->f() << '\n';
}
Obviously the clone code works. Thing is, there's some things in it I'd like to avoid:
raw new.
a random function that needs to be part of the interface.
This function returns a raw pointer.
Every user of this class that wants to be copyable needs to call this function.
So, is there a "clean" alternative?
Note I want to use smart pointers for all the obvious reasons, I just need a deep copying std::unique_ptr. Something like std::copyable_unique_ptr, combining optional move semantics with a deep copying copy constructor. Is this the cleanest way? Or does that only add the the confusion?
You can certainly create a clone_ptr-class for any object you know statically how to clone.
It would hold a pointer to the object, and a pointer to a function for cloning said object, probably from converting a stateless lambda.

an iterator that constructs a new object on dereference

I have a Visual Studio 2013 C++11 project where I'm trying to define an iterator. I want that iterator to dereference to an object, but internally it actually iterates over some internal data the object requires for construction.
class my_obj
{
public:
my_obj(some_internal_initialization_value_ v);
std::wstring friendly_name() const;
// ...
};
class my_iterator
: public boost::iterator_facade<
my_iterator,
my_obj,
boost::forward_traversal_tag>
{
// ...
private:
my_obj& dereference() const
{
// warning C4172: returning address of local variable or temporary
return my_obj(some_internal_initialization_value_);
}
};
int main( int argc, char* argv[])
{
my_container c;
for (auto o = c.begin(); o != c.end(); ++o)
printf( "%s\n", o->friendly_name().c_str() );
}
These internal values are unimportant implementation details to the user and I'd prefer not to expose them. How can I write the iterator that does this correctly? The alternative is that I would have to do something like this:
my_container c;
for (auto i = c.begin(); i != c.end(); ++i)
{
my_obj o(*i);
printf( "%s\n", o.friendly_name().c_str() );
}
From the boost page on iterator_facade, the template arguments are: derived iterator, value_type, category, reference type, difference_type. Ergo, merely tell it that references are not references
class my_iterator
: public boost::iterator_facade<
my_iterator,
my_obj,
boost::forward_traversal_tag,
my_obj> //dereference returns "my_obj" not "my_obj&"
See it working here: http://coliru.stacked-crooked.com/a/4b09ddc37068368b

Resources