Polymorphic behavior with shared pointers - c++11

I am new to shared_ptr struff. So this may be a silly question, but i have no clue of the error i am getting.
#include<iostream>
#include<vector>
#include<memory>
#include<algorithm>
using namespace std;
class base
{
public:
base() { cout<<" base::ctor "<<endl; }
virtual void print() { cout<<" base::print "<<endl; }
virtual ~base() { cout<<" base::dtor "<<endl; }
};
class derived : public base
{
public:
derived() { cout<<" derived:ctor "<<endl; }
void print() { cout<<" derived::print "<<endl; }
~derived() { cout<<" derived::dtor "<<endl; }
};
typedef shared_ptr<base> sPtr;
int main()
{
vector<sPtr> v;
v.push_back(make_shared<derived>());
cout<<endl;
v.push_back(make_shared<derived>());
cout<<endl;
// for_each(v.begin(), v.end(), [](sPtr sp) { sp.print(); });
for(auto elem : v)
elem.print();
return 0;
}
Error :
sharedPtr.cpp: In function ‘int main()’:
sharedPtr.cpp:34:14: error: ‘class std::shared_ptr<base>’ has no member named ‘print’
elem.print();
^
With my limited understanding, elem should be a shared pointer of type "base", should have called print of derived class as it's a virtual function.
What's wrong with this code?

Related

C++ Access member function using pointer

I am not able to access member function using pointer.Find the below code and Error message
The Error message is mentioned here
error: request for member ‘getstream’ in ‘* objA.A::getfunction()’, which is of non-class type ‘int’
ret = objA.getfunction()->getstream();
#include <iostream>
using namespace std;
class A {
public:
int *getfunction();
int getstream();
};
int* A::getfunction()
{
static int a;
a= getstream();
return &a;
}
int getstream()
{
return 1;
}
int main()
{
int *ret;
A objA;
ret = objA.getfunction()->getstream();
cout << ret;
return 0;
}
If you want to achieve a syntax like objA.getfunction()->getstream(); in your main function,
you can do it with class A implementation similar to this :
#include <iostream>
using namespace std;
// class A declaration
class A {
public:
// Nested class A::AFunction declaration
class AFunction {
public:
int getstream();
};
private:
AFunction *p_AFunction;
public:
A();
~A();
A::AFunction *getfunction();
}; // class A
// class A member function implementations
A::A() : p_AFunction(new AFunction()) {
}
A::~A() {
delete p_AFunction;
p_AFunction = nullptr;
}
A::AFunction *A::getfunction() {
return p_AFunction;
}
// Nested class A::AFunction member function implementations
int A::AFunction::getstream() {
return 1;
}
// main function
int main() {
A objA;
int ret = objA.getfunction()->getstream();
cout << ret;
return 0;
}
If you want A::getfunction() function to return a function pointer to a member function in class A, and then invoke it in main function, you can have a implementation similar to this :
#include <iostream>
using namespace std;
// class A declaration
class A {
public:
typedef int (A::*AMemberFuncPtr) ();
private:
AMemberFuncPtr fn_getstream;
public:
A();
A::AMemberFuncPtr getfunction();
private:
int getstream();
}; // class A
// class A member function implementations
A::A() : fn_getstream(&A::getstream) {
}
A::AMemberFuncPtr A::getfunction() {
return fn_getstream;
}
int A::getstream() {
return 1;
}
// main function
int main() {
A objA;
int ret = (objA.*objA.getfunction())();
cout << ret;
return 0;
}
Also see the answer to Function pointer to member function.

Custom compare class not working as I expect for pointers to a user defined class in a std::set container

I can't figure out why in this code example the std::set container is not ordering the Entities as I expect on the basis of the compare class I defined. Anyone can help me please? Thanks
#include <iostream>
#include <set>
class Entity {
public:
int num;
Entity(int num):num(num){}
bool operator< (const Entity& _entity) const { return (this->num < _entity.num); }
};
struct my_cmp {
bool operator() (const Entity* lhs, const Entity* rhs) const { return (lhs < rhs); }
};
class EntityManager {
private:
std::set<Entity*, my_cmp> entities;
public:
void AddEntity(int num) { entities.insert(new Entity(num)); }
void ListAllEntities() const {
unsigned int i = 0;
for (auto& entity: entities) {
std::cout << "Entity[" << i << "]: num:" << entity->num << std::endl;
i++;
}
}
};
int main(void) {
EntityManager manager;
manager.AddEntity(2);
manager.AddEntity(1);
manager.AddEntity(4);
manager.AddEntity(3);
manager.ListAllEntities();
return 0;
}
Output:
Entity[0]: num:2
Entity[1]: num:1
Entity[2]: num:4
Entity[3]: num:3
I would expect the following output instead:
Entity[1]: num:1
Entity[0]: num:2
Entity[3]: num:3
Entity[2]: num:4
You need to dereference your pointers *lhs < *rhs. You're just comparing the value of the pointers currently, so your order is dependent on their location in memory.
#include <iostream>
#include <set>
class Entity {
public:
int num;
Entity(int num):num(num){}
bool operator< (const Entity& _entity) const { return (this->num < _entity.num); }
};
struct my_cmp {
bool operator() (const Entity* lhs, const Entity* rhs) const { return (*lhs < *rhs); }
};
class EntityManager {
private:
std::set<Entity*, my_cmp> entities;
public:
void AddEntity(int num) { entities.insert(new Entity(num)); }
void ListAllEntities() const {
unsigned int i = 0;
for (auto& entity: entities) {
std::cout << "Entity[" << i << "]: num:" << entity->num << std::endl;
i++;
}
}
};
int main(void) {
EntityManager manager;
manager.AddEntity(2);
manager.AddEntity(1);
manager.AddEntity(4);
manager.AddEntity(3);
manager.ListAllEntities();
return 0;
}
Demo

Error in storing outer class object in inner class C++

I was implementing the ring buffer and have encountered an error. What does it mean to store a reference of outer class(class ring) object(m_ring) in inner class(class iterator) and when I remove the reference(&) the program compiles correctly but crashes. Please explain what is happening.(See the comment in Ring.h) Sorry for bad English.
// Ring.h
#ifndef RING.H
#define RING.H
#include <iostream>
using namespace std;
template<class T>
class ring {
unsigned int m_size;
int m_pos;
T *m_values;
public:
class iterator;
public:
ring(unsigned int size) : m_size(size), m_pos(0)
{
m_values = new T[m_size];
}
~ring()
{
delete[] m_values;
}
void add(const T &val)
{
m_values[m_pos] = val;
m_pos++;
m_pos %= m_size;
}
T& get(int pos)
{
return m_values[pos];
}
iterator begin()
{
return iterator(0, *this);
}
iterator end()
{
return iterator(m_size, *this);
}
};
template<class T>
class ring<T>::iterator {
int m_pos;
ring &m_ring; // Removing & gives garbage output.
public:
iterator(int pos, ring& aRing) : m_pos(pos), m_ring(aRing){}
bool operator!=(const iterator &other) const
{
return other.m_pos != m_pos;
}
iterator &operator++(int)
{
m_pos++;
return *this;
}
iterator &operator++()
{
m_pos++;
return *this;
}
T &operator*()
{
// return m_ring.m_values[m_pos];
return m_ring.get(m_pos);
}
};
#endif // RING
Driver program :
// Ring_Buffer_Class.cpp
#include <iostream>
#include "ring.h"
using namespace std;
int main()
{
ring<string> textring(3);
textring.add("one");
textring.add("two");
textring.add("three");
textring.add("four");
// C++ 98
for(ring<string>::iterator it = textring.begin(); it != textring.end(); it++)
{
cout << *it << endl;
}
cout << endl;
// C++11
for(string value : textring)
{
cout << value << endl;
}
return 0;
}
I also observed that removing ~ring() (Destructor) results into correct output.
Expected output :
four
two
three
four
two
three

Rcpp: Calling function with object as argument

I have a function in Rcpp, which creates a very long map-structure within a class. I've given a simple example of it below:
#include <Rcpp.h>
using namespace Rcpp;
class A{
private:
std::map<int, int> m_map;
public:
void fill_map(const size_t limit){
for(size_t i=0; i<limit; ++i){
m_map[i] = i;
}
}
size_t size_map(){return m_map.size();}
};
// [[Rcpp::export]]
void func1(const size_t limit) {
A a;
a.fill_map(limit);
}
/* NOT WORKING */
// [[Rcpp::export]]
void func2(A a)
{
std::cout << a.size_map() << "\n";
}
/* NOT WORKING */
Say I call func1(1e7), which fills up the map in the a-object. I need to pass this A-object to other functions as shown above with func2.
However, my example with func2 doesn't work. Within the Rcpp-framework, what is the correct and most efficient approach to call func2 with an object defined in a previous function?
C++ code
#include <Rcpp.h>
using namespace Rcpp;
class A
{
private:
std::map<int, int> m_map;
public:
void fill_map(const size_t limit)
{
for(size_t i=0; i<limit; ++i)
{
m_map[i] = i;
}
}
size_t size_map(){return m_map.size();}
};
// [[Rcpp::export]]
XPtr<A> func1(const size_t limit)
{
XPtr<A> ptr(new A(), true);
ptr->fill_map(limit);
return(ptr);
}
// [[Rcpp::export]]
void func2(XPtr<A> ptr)
{
Rcout << ptr->size_map() << std::endl;
}
R code
a = func1(10)
func2(a)
a being an External pointer.

Function move could not be resolved, Semantic Error

The following program which is supposed to emulate std::vector. I am using Eclipse IDE for C/C++ Developers
Version: Neon.3 Release (4.6.3)
Build id: 20170314-1500
and my c++ version is g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
is flagging error that "function std::move could not be resolved".
What is the possible reason for this error ?
//============================================================================
// Name : data_structure_1.cpp
// Author : Manish Sharma
// Description : Programme to implement a simple vector class named "Vector".
// Reference : Data Structures and Algo. analysis in c++, Mark Allen Weiss
//============================================================================
#include <iostream>
#include <algorithm>
using namespace std;
template<class Object>
class Vector{
public:
// constructor
explicit Vector(int initSize = 0):
theSize{initSize},
theCapacity{initSize + SPARE_CAPACITY},
objects{new Object[theCapacity]}{
}
// copy constructor
Vector(const Vector& rhs):
theSize{rhs.theSize},
theCapacity{rhs.theCapacity},
objects{new Object[theCapacity]}{
for(int k = 0;k<theSize; ++k){
objects[k] = rhs.objects[k];
}
}
// copy assignment operaor
Vector & operator= (const Vector & rhs){
Vector copy = rhs;
std::swap(*this,copy);
return *this;
}
//class destructor
~Vector(){
delete[] objects;
}
//c++ 11 additions, reference to rvalues
Vector(Vector&& rhs) :
theSize{rhs.theSize},
theCapacity{rhs.theCapacity},
objects{rhs.objects}{
cout<<endl<<"Inside lvalue reference constructor";
//if you forget to include this then when rhs will you destroyed
//you will be left with a dangling pointer
rhs.objects = nullptr;
rhs.theSize = 0;
rhs.theCapacity = 0;
}
// copy assignment operaor
Vector & operator= (Vector && rhs){
cout<<endl<<"Inside lvalue reference copy";
Vector copy = rhs;
std::swap(*this,copy);
return *this;
}
void resize(int newSize){
if(newSize > theCapacity)
reserve(newSize*2);
theSize = newSize;
}
void reserve(int newCapacity){
if(newCapacity<theSize)
return;
Object *newArray = new Object[newCapacity];
cout<<endl<<"moving inside reserve";
for(int k=0;k<theSize;++k){
newArray[k] = std::move(objects[k]);
}
theCapacity = newCapacity;
std::swap(objects,newArray);
delete[] newArray;
}
//Some extra useful functions
int size() const{
return theSize;
}
bool empty() const{
return size()==0;
}
int capacity() const{
return theCapacity;
}
void increaseCapacity(){
reserve(2*theCapacity+1);
}
//insertion and deletion functions
void push_back(const Object & x){
if(theSize == theCapacity){
increaseCapacity();
}
cout<<endl<<"Moving inside push_back";
objects[theSize++] = std::move(x);
}
void pop_back(){
--theSize;
}
using iterator = Object*;
using const_iterator = const Object*;
iterator begin(){
return &objects[0];
}
const_iterator begin() const{
return &objects[0];
}
iterator end(){
return &objects[size()];
}
const_iterator end() const{
return &objects[size()];
}
//class specific constants
static const int SPARE_CAPACITY = 16;
private:
int theSize;
int theCapacity;
Object * objects;
};
int main() {
Vector<int> my_vector;
my_vector.push_back(10);
int j{24};
my_vector.push_back(j);
for(int i = 0;i<20;i++){
my_vector.push_back(i*10);
}
cout<<"\nSize = "<<my_vector.size()<<endl;
my_vector.capacity();
for(auto it = my_vector.begin();it!=my_vector.end();++it){
cout<<*it<<", ";
}
return 0;
}

Resources