I am pretty new to C++ and have a problem regarding pointers/references. The following example reflects my problem:
#include <iostream>
#include "boost/make_shared.hpp"
#include "boost/utility.hpp"
class UsedObjectInterface {
public:
virtual int data() const = 0;
};
class UsedObject : public UsedObjectInterface {
public:
UsedObject() : data_(42) {
}
explicit UsedObject(int value) : data_(value) {
}
int data() const {
return data_;
}
private:
const int data_;
};
class BaseClient : private boost::noncopyable {
public:
virtual const UsedObjectInterface& used_object() const = 0;
};
class SegmentationFaultClient : public BaseClient {
public:
// This can't work, since the object is deleted immediately.
// IMHO only the following two solutions can work:
// 1. The member attribute is not a reference (not possible with an abstract class, we lose the advantages of polymorphism).
// 2. The member attribute is a pointer.
SegmentationFaultClient() : used_object_(UsedObject()) {
}
explicit SegmentationFaultClient(const UsedObjectInterface& used_object)
: used_object_(used_object) {
}
const UsedObjectInterface& used_object() const {
return this->used_object_;
}
private:
const UsedObjectInterface& used_object_;
};
class CorrectClient : public BaseClient {
public:
CorrectClient() : used_object_(boost::make_shared<UsedObject>()) {
}
explicit CorrectClient(const boost::shared_ptr<UsedObjectInterface> used_object)
: used_object_(used_object) {
}
// TODO Is it possible to change this to a const&, so at least the interface
// is the same as in SegmentationFaultClient? Then the above constructor can
// be deleted.
explicit CorrectClient(const UsedObjectInterface& used_object)
: used_object_(&used_object) {
// TODO How-to convert a raw pointer to a smart pointer?
}
const UsedObjectInterface& used_object() const {
return *this->used_object_;
}
private:
const boost::shared_ptr<UsedObjectInterface> used_object_;
};
int main() {
SegmentationFaultClient segfault_client;
const UsedObjectInterface& a = segfault_client.used_object();
std::cout << a.data() << std::endl;
// Correct, but how to make this work with a const& constructor?
const UsedObject first_object;
CorrectClient correct_client(first_object);
const UsedObjectInterface& b = correct_client.used_object();
std::cout << b.data() << std::endl;
}
As the comments say, the implementaton of the SegmentationFaultClient class is simply wrong, since the default constructor creates an object on the stack, which is "immediately" removed. Therefore I came up with the class CorrectClient, which uses pointers. My goal is to keep the nice API (no public Boost) from SegmentationFaultClient (const& default constructor). The above example does not work and terminates with the following error:
invalid conversion from 'const UsedObjectInterface*' to 'boost::shared_ptr<UsedObjectInterface>::element_type* {aka UsedObjectInterface*}' [-fpermissive]
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
So my question is: Is it possible to convert a raw pointer * to a smart pointer? If so, what is the best way to do that? If you see any other problems with my code, please let me know, too!
Problem is, that you are trying to convert const-pointer to a non-const pointer. You can use reference as param, instead of const-reference, or you can do following
const boost::shared_ptr<const UsedObjectInterface> used_object_;
However, default-deleter for shared_ptr will be delete pointer, that is in your case not allocated on heap. You should point empty-deleter, or not use shared_ptr in this case.
Related
I am trying to replace raw pointers with smart pointers.
class MyObj {
public:
MyObj() {
rawContainer = new BigObj();
}
const BigObj* GetRawObj() {
return rawContainer;
}
private:
BigObj* rawContainer;
};
When I call
auto rawObj = myObj.GetRawObj() I avoid copying BigObj and can only call the functions marked const, so I can't modify it's content.
class MyObj {
public:
MyObj() {
std::unique_ptr<BigObj> ptr(new BigObj());
container = std::move(ptr);
}
const std::unique_ptr<BigObj>& GetObj() {
return container;
}
private:
std::unique_ptr<BigObj> container;
};
This time, with auto smartObj = myObj.GetObj(); I can access non-const methods of smartObj.
I understand the definition const std::unique_ptr<BigObj>& GetObj() is making the reference constant, and not the underlying object, but changing it to const std::unique_ptr<const BigObj>& GetObj() creates a compiler error.
Is there a sensible way to do this? I've seen suggestion of just returning a raw pointer from the smart pointer and using it like in the first example. The actual object in MyObj can't be const since it can actually be modified by some methods.
It is perfectly valid to declare const std::unique_ptr<const BigObj>& GetObj().
The problem must be somewhere else.
#include <memory>
class BigObj
{
};
class MyObj
{
public:
MyObj(): container(std::make_unique<BigObj>()) {}
auto GetObj() -> const std::unique_ptr<const BigObj>&
{
return reinterpret_cast<const std::unique_ptr<const BigObj>&>(container);
}
private:
std::unique_ptr<BigObj> container;
};
auto main()->int
{
MyObj obj;
obj.GetObj();
}
https://onlinegdb.com/xzHzI4GgM
Like the commenters above is suggesting. Just return a raw pointer. There is no reason to return a reference to the unique_ptr below.
#include <memory>
struct BigObj {
int bigData = 1000;
};
class MyObj {
public:
const BigObj& getObj() const {
return *container;
}
// Alternative if you want a pointer instead of a reference
// (you probably don't if you know that the pointer is non null)
//const BigObj* getObj2() const {
// return container.get();
//}
private:
std::unique_ptr<BigObj> container = std::make_unique<BigObj>();
};
int main() {
auto myObj = MyObj{};
auto &ref = myObj.getObj();
}
Note: There is syntax if you want to be able to move a ptr out of the object, but I guess that that is not a part of the question.
For a concrete example, say I am given
vector<shared_ptr<DClass>> cVector
and DClass (which is derived from MyClass) has the following interface
class DClass: public MyClass {
public:
DClass( string id, string name, int p, int v )
: MyClass id, name, p ), var1_ ( v ) {}
int GetDClassVar1() const { return var1_; }
private:
int var1_;
};
and MyClass (which DClass inherits from) has the following interface
class MyClass {
public:
MyClass( string id, string name, int p )
: id_( id ), name_( name ), myclassvar1__( p ) {}
string GetMyClassID() const { return id_; }
string GetMyClassName() const { return name_; }
int GetMyClassVar1() const { return myclassvar1__; }
virtual int GetDClassVar1() const { return 0; }
protected:
string id_;
string name_;
int myclassvar1_;
};
How can I call upon the GetDClassVar1 function using cVector assuming that cVector is populated?
***EDIT
I try using
cVector.at(1).GetDClassVar1.()
and I get the error
const value_type’ {aka ‘const class std::shared_ptr<MyClass>’} has no member
named ‘GetDClassVar1'
How can I call upon the GetDClassVar1 function using cVector assuming that cVector is populated
for (const auto& d : cVector)
std::cout << d->GetDClassVar1() << "\n";
Note that when calling a member function that is not const-qualified, you need to remove the const before auto&. For a single element:
cVector.front()->getDClassVar1();
cVector.at(42)->getDClassVar1();
This syntax is due to the fact that std::shared_ptr has an overloaded operator -> member function that forwards to the underlying pointer.
Also note that you want polymorphic base classes to have a virtual destructor, see here.
To access the members of a pointer, you have to use -> instead of .. Other than that, it's pretty much the same!
int result = cVector[0]->GetDClassVar1();
Alternatively, you could dereference it first:
int result = (*cVector[0]).GetDClassVar1();
Or bind it to a reference, if you're doing multiple operations on it:
auto& element = *cVector[0];
int result = element.GetDClassVar1();
Suppose I have a class that has an array of pointers, and I have a method that dereferences a pointer and returns it as a reference. I want to allow the method caller to call non-const methods of the object the pointer is pointing to, but also want to protect myself from the caller changing what the pointer is pointing to. If I return a const reference, I have to mark many of the pointer object's methods as const, and hence many of its class member variables as mutable.
Is this bad practice? If so, how do I get around this?
Is there performance penalty for over-using mutable?
Example:
#include <iostream>
#include <array>
#include <memory>
class Counter
{
public:
Counter();
void hit() const;
void reset();
unsigned count() const;
private:
mutable unsigned count_;
};
Counter::Counter() : count_(0) {}
void Counter::hit() const { ++count_; }
void Counter::reset() { count_ = 0; }
unsigned Counter::count() const { return count_; }
class CircularArray
{
public:
CircularArray();
const Counter& next() const;
private:
mutable unsigned i_;
std::array<std::unique_ptr<Counter>, 3> arr_;
};
CircularArray::CircularArray() : i_(2)
{
arr_[0] = std::unique_ptr<Counter>(new Counter);
arr_[1] = std::unique_ptr<Counter>(new Counter);
arr_[2] = std::unique_ptr<Counter>(new Counter);
}
const Counter& CircularArray::next() const { return *arr_[(i_ = (i_ + 1) % 3)]; }
int main()
{
CircularArray circular;
const Counter* p;
p = &circular.next();
p->hit();
p->hit();
Counter c;
//*p = c; // <-- Want to prevent this
}
To extend what I was saying, there is no point in abusing mutable for this. If this is all you want to prevent:
*p = /* ... */;
then it can be done much more easily by deleting the assignment operator of Counter:
class Counter
{
void operator=(const Counter&) = delete;
// ...
};
Remember that the assignment operator does not affect the identity of the object: it doesn't change its address. Semantically, an assignment involving of modifying this object to replicate the state of another object. In fact, even if you forbid me from using the assignment operator somehow, I could still do this:
// a very inefficient way of performing `*p = c`
p->reset();
while (p->count() != c.count())
p->hit();
This achieves the exact same result as performing an assignment, albeit very clumsily and inefficiently.
Performing an assignment is no different than calling a non-const member function that accepts a single argument of type const Counter&. Hypothetically, you could redefine the assignment operator to do absolutely nothing at all if you wanted to (it would be a bad idea though).
I have a void pointer and I would like to get the content of what the pointer refers to.
void class :: method(void * pointer)
{
cout<<pointer; // The address which the pointer refers to.
cout<<?; //The content of where the pointer refers to.
}
The original type of pointer is unknown.
EDIT: The goal is to allow create a "generic method" which gets any type of argument, and do the same actions for each.
The limitation is that the method is virtual and therefore I cannot use template method.
You need to cast the void* back to its original type (ie. before it was cast to void*). Then you can dereference the pointer and use what it's pointing to.
Eg. :
void fun(void* ptr) {
int* iptr = (int*) ptr;
std::cout << *iptr;
}
int* iptr = new int(42);
fun(iptr);
One way to do this in a way that fits your specific use case, is to pass on the type information with the object using a generic type like boost::any :
#include <iostream>
#include <string>
#include <boost/any.hpp>
class Foo {
public :
virtual void fun(const boost::any& obj) {
if (typeid(int) == obj.type()) {
std::cout << boost::any_cast<int>(obj) << std::endl;
}
else if (typeid(std::string) == obj.type()) {
std::cout << boost::any_cast<std::string>(obj) << std::endl;
}
else {
std::cout << "unsupported type" << std::endl;
}
}
};
int main(void) {
Foo foo;
int i = 42;
std::string s = "str";
float f = 1.1f;
foo.fun(i);
foo.fun(s);
foo.fun(f);
return 0;
}
But that can get very verbose, depending on how many types you want to support.
This is impossible. The types in C++ are (mostly) a compile-time property. At runtime, types are unknown (they are erased).
However, RTTI exist, notably for instances of some class containing virtual methods.
There is no possible trick in general. You could redesign your program by having some kind of variant type, or by having a common root class from which all your objects inherit, etc etc, or by using union types (better have your own discriminated unions).
Put it another way: when the compiler see a void* pointer, it does not even know the size of the data pointed by that pointer.
Future C++ standards might propose some std::any container.
Maybe you could have something like a cheap discriminated union class like
class Int_or_String {
const bool isint;
union {
int n;
std::string s;
};
Int_or_String(const int i) : isint(true), n(i) {};
Int_or_String(const std::string &st): isint(false), s(st) {};
~Int_or_String() { if (isint) n=0; else
/*not sure*/ s.std::string::~std::string(); };
// much more is missing
};
I'm not even sure of the syntax to explicitly destroy a union member.
See e.g. this question on calling destructors explicitly
Perhaps the Qt object model might inspire you. Look also into its QVariant
The usual way is to define a root class in your program and adopt the convention that all your objects are inheriting this root class (or even that all your meaningful data are in objects derived from that root class). This requires a redesign of the whole thing.
So you would decide that your root class is e.g
class Root {
public:
virtual void out(std::ostream&s) =0;
virtual ~Root() =0;
/// other common methods
};
static inline std::ostream& operator << (std::ostream&o, const Root &r)
{ r.out(o); return o; }
class Integer : public Root {
const int num;
public:
Integer(int n) : Root(), num(n) {};
void out (std::ostream &o) { o << num ; };
/// etc...
}; // end class Num
class String : public Root {
const std::string str;
public:
String(const std::string& s) : Root(), str(s) {};
void out (std::ostream &o) { o << str ; };
/// etc...
}; // end class String
I've got an interesting problem that's cropped up in a sort of pass based compiler of mine. Each pass knows nothing of other passes, and a common object is passed down the chain as it goes, following the chain of command pattern.
The object that is being passed along is a reference to a file.
Now, during one of the stages, one might wish to associate a large chunk of data, such as that file's SHA512 hash, which requires a reasonable amount of time to compute. However, since that chunk of data is only used in that specific case, I don't want all file references to need to reserve space for that SHA512. However, I also don't want other passes to have to recalculate the SHA512 hash over and over again. For example, someone might only accept files which match a given list of SHA512s, but they don't want that value printed when the file reference gets to the end of the chain, or perhaps they want both, or... .etc.
What I need is some sort of container which contain only one of a given type. If the container does not contain that type, it needs to create an instance of that type and store it somehow. It's basically a dictionary with the type being the thing used to look things up.
Here's what I've gotten so far, the relevant bit being the FileData::Get<t> method:
class FileData;
// Cache entry interface
struct FileDataCacheEntry
{
virtual void Initalize(FileData&)
{
}
virtual ~FileDataCacheEntry()
{
}
};
// Cache itself
class FileData
{
struct Entry
{
std::size_t identifier;
FileDataCacheEntry * data;
Entry(FileDataCacheEntry *dataToStore, std::size_t id)
: data(dataToStore), identifier(id)
{
}
std::size_t GetIdentifier() const
{
return identifier;
}
void DeleteData()
{
delete data;
}
};
WindowsApi::ReferenceCounter refCount;
std::wstring fileName_;
std::vector<Entry> cache;
public:
FileData(const std::wstring& fileName) : fileName_(fileName)
{
}
~FileData()
{
if (refCount.IsLastObject())
for_each(cache.begin(), cache.end(), std::mem_fun_ref(&Entry::DeleteData));
}
const std::wstring& GetFileName() const
{
return fileName_;
}
//RELEVANT METHOD HERE
template<typename T>
T& Get()
{
std::vector<Entry>::iterator foundItem =
std::find_if(cache.begin(), cache.end(), boost::bind(
std::equal_to<std::size_t>(), boost::bind(&Entry::GetIdentifier, _1), T::TypeId));
if (foundItem == cache.end())
{
std::auto_ptr<T> newCacheEntry(new T);
Entry toInsert(newCacheEntry.get(), T::TypeId);
cache.push_back(toInsert);
newCacheEntry.release();
T& result = *static_cast<T*>(cache.back().data);
result.Initalize(*this);
return result;
}
else
{
return *static_cast<T*>(foundItem->data);
}
}
};
// Example item you'd put in cache
class FileBasicData : public FileDataCacheEntry
{
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
unsigned __int64 size;
public:
enum
{
TypeId = 42
}
virtual void Initialize(FileData& input)
{
// Get file attributes and friends...
}
DWORD GetAttributes() const;
bool IsArchive() const;
bool IsCompressed() const;
bool IsDevice() const;
// More methods here
};
int main()
{
// Example use
FileData fd;
FileBasicData& data = fd.Get<FileBasicData>();
// etc
}
For some reason though, this design feels wrong to me, namely because it's doing a whole bunch of things with untyped pointers. Am I severely off base here? Are there preexisting libraries (boost or otherwise) which would make this clearer/easier to understand?
As ergosys said already, std::map is the obvious solution to your problem. But I can see you concerns with RTTI (and the associated bloat). As a matter of fact, an "any" value container does not need RTTI to work. It is sufficient to provide a mapping between a type and an unique identifier. Here is a simple class that provides this mapping:
#include <stdexcept>
#include <boost/shared_ptr.hpp>
class typeinfo
{
private:
typeinfo(const typeinfo&);
void operator = (const typeinfo&);
protected:
typeinfo(){}
public:
bool operator != (const typeinfo &o) const { return this != &o; }
bool operator == (const typeinfo &o) const { return this == &o; }
template<class T>
static const typeinfo & get()
{
static struct _ti : public typeinfo {} _inst;
return _inst;
}
};
typeinfo::get<T>() returns a reference to a simple, stateless singleton which allows comparisions.
This singleton is created only for types T where typeinfo::get< T >() is issued anywhere in the program.
Now we are using this to implement a top type we call value. value is a holder for a value_box which actually contains the data:
class value_box
{
public:
// returns the typeinfo of the most derived object
virtual const typeinfo& type() const =0;
virtual ~value_box(){}
};
template<class T>
class value_box_impl : public value_box
{
private:
friend class value;
T m_val;
value_box_impl(const T &t) : m_val(t) {}
virtual const typeinfo& type() const
{
return typeinfo::get< T >();
}
};
// specialization for void.
template<>
class value_box_impl<void> : public value_box
{
private:
friend class value_box;
virtual const typeinfo& type() const
{
return typeinfo::get< void >();
}
// This is an optimization to avoid heap pressure for the
// allocation of stateless value_box_impl<void> instances:
void* operator new(size_t)
{
static value_box_impl<void> inst;
return &inst;
}
void operator delete(void* d)
{
}
};
Here's the bad_value_cast exception:
class bad_value_cast : public std::runtime_error
{
public:
bad_value_cast(const char *w="") : std::runtime_error(w) {}
};
And here's value:
class value
{
private:
boost::shared_ptr<value_box> m_value_box;
public:
// a default value contains 'void'
value() : m_value_box( new value_box_impl<void>() ) {}
// embedd an object of type T.
template<class T>
value(const T &t) : m_value_box( new value_box_impl<T>(t) ) {}
// get the typeinfo of the embedded object
const typeinfo & type() const { return m_value_box->type(); }
// convenience type to simplify overloading on return values
template<class T> struct arg{};
template<class T>
T convert(arg<T>) const
{
if (type() != typeinfo::get<T>())
throw bad_value_cast();
// this is safe now
value_box_impl<T> *impl=
static_cast<value_box_impl<T>*>(m_value_box.get());
return impl->m_val;
}
void convert(arg<void>) const
{
if (type() != typeinfo::get<void>())
throw bad_value_cast();
}
};
The convenient casting syntax:
template<class T>
T value_cast(const value &v)
{
return v.convert(value::arg<T>());
}
And that's it. Here is how it looks like:
#include <string>
#include <map>
#include <iostream>
int main()
{
std::map<std::string,value> v;
v["zero"]=0;
v["pi"]=3.14159;
v["password"]=std::string("swordfish");
std::cout << value_cast<int>(v["zero"]) << std::endl;
std::cout << value_cast<double>(v["pi"]) << std::endl;
std::cout << value_cast<std::string>(v["password"]) << std::endl;
}
The nice thing about having you own implementation of any is, that you can very easily tailor it to the features you actually need, which is quite tedious with boost::any. For example, there are few requirements on the types that value can store: they need to be copy-constructible and have a public destructor. What if all types you use have an operator<<(ostream&,T) and you want a way to print your dictionaries? Just add a to_stream method to box and overload operator<< for value and you can write:
std::cout << v["zero"] << std::endl;
std::cout << v["pi"] << std::endl;
std::cout << v["password"] << std::endl;
Here's a pastebin with the above, should compile out of the box with g++/boost: http://pastebin.com/v0nJwVLW
EDIT: Added an optimization to avoid the allocation of box_impl< void > from the heap:
http://pastebin.com/pqA5JXhA
You can create a hash or map of string to boost::any. The string key can be extracted from any::type().