codeLover
codeLover

Reputation: 3810

What is the Equivalent of "object of C# " in VC++?

In C# we have a datatype object which can hold any type of data. Same thing I want to achieve in VC++. Can anyone kindly let me know VC++ equivalent of "Object of C#".
IN C#, in the calling appl program (say call.cs)

object ob=null;
ob=(object)str; 
 funct(ref ob);

Here str is empty string.

This thing I want to achieve in VC++. So I need to create VC++ equivalent of object. I am sure we need to use pointers as ref's equivalent??

Upvotes: 4

Views: 8273

Answers (5)

Moo-Juice
Moo-Juice

Reputation: 38810

As other commentators have said, C++ does not have a common base-class for every object. Theoretically, you could create your own and derive everything from it:

class Object
{
protected:
    Object(){};
    virtual ~Object(){};

public:
    virtual std::string toString() const {return("");};
}; // eo class Object

This, however, won't help you with integral types such as int, short. You'd have to make your own:

class Int : public Object
{
private:
    int m_nVal;

public:
    Int(int _val = 0) : m_nVal(_val){};
    Int(const Int& _rhs) : m_nVal(_rhs.m_nVal){};
    virtual ~Int(){};

    // operators
    operator int() const {return(m_nVal);}
    bool operator == (const Int& _rhs) const {return(m_nVal == _rhs.m_nVal);};
    bool operator == (int _val) const {return(m_nVal == _val);};
    Int& operator = (const Int& _rhs) {m_nVal = _rhs.m_nVal; return(*this);}:
    Int& operator = (int _val) {m_nVal = _val; return(*this);};
    // .... and all the other operators

    // overrides
    virtual std::string toString() const
    {
       std::ostringstream oss;
       oss << m_nVal;
       return(oss.str());
    };
}; // eo class Int

You'd then have to do this for all the other types you want to use. Once done you can pass them around as if they were ints, bools, longs etc (thanks to operator overloading). A better method would be to use a template class for the integral types:

template<class T> class IntegralType : public Object
{
private:
    T m_Val;

public:
    // rest of class looks the same
}; // eo class IntegralType<>

Then typedef them away:

typedef IntegralType<int> Int;
typedef IntegralType<short> Short;
typedef IntegralType<long> Long;

Even using a template-class like this to take the leg-work out of it, you'd still need a specialisation for strings/bools. implementing operator ++ on IntegralType<> will work fine for numbers, but is going to throw up on std::string.

If you went the template route, you've now got "Object", integral types and some specialisations for strings, bools. But to mimick .NET even more, you probably want to introduce interfaces for comparisons:

template<class T> class IEquitable
{
public:
    virtual Equals(T _other) = 0;
};   // eo class IEquitable<>

That can easily be plumbed in to your IntegralType<> classes and the specialisations.

But as another commentator pointed out, why would you? boost::any is useful if you're trying to do something like a Tuple which has a name and a value of an arbitrary type. If you need to build a collection of these then there is something fundamentally wrong with your design. For example, in all my coding in C# I have never had to write:

List<Object> list = new List<Object>();

There may have been:

List<Vehicle> list;
List<Employee> List;
Dictionary<string, Alien> aliens;

But never anything at the Object level. Why? Well apart from calling ToString() on it, or perhaps doing some risky casting, why would you want to? Generics exist in programming so that we do not have to have lists of objects (or in the case of C++, void*).

So there you have it. The above shows how you might have objects and integral types working kind of like C#, and I've missed a chunk of stuff out. Now it's time to look at your design and decide if that's what you really need to do.

Upvotes: 9

Hans Passant
Hans Passant

Reputation: 942000

The <comutil.h> header contains a handy wrapper for VARIANT. Takes care of proper initialization and cleanup.

#include <comutil.h>
#ifdef _DEBUG
#  pragma comment(lib, "comsuppwd.lib")
#else
#  pragma comment(lib, "comsuppw.lib")
#endif
...
    _variant_t arg = L"some string";
    someComPtr->func(&arg);

There isn't anything in your code snippet that would help me help you figuring out how to obtain the COM interface pointer. Start a new question about that if you have trouble.

Upvotes: 5

weismat
weismat

Reputation: 7411

The alternative for you is to look at System.Runtime.InteropServices.GCHandle, which allows you to find the managed object from unmanaged code, but in any way you will end up with nasty and risky type casts and you need to be really careful to keep somewhere a reference to the managed object as it might get garbage-collected if there is only a reference in unmanaged code.

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490338

There's nothing built into the language. Usually, wanting it at all indicates that your design isn't very well thought out, but if you can't figure out any alternative, you might consider (for one example) Boost any.

Upvotes: 5

James McNellis
James McNellis

Reputation: 355187

There isn't one. C++ doesn't have a unified type hierarchy like .NET languages have.

The closest you can get is a void* (pointer-to-void), which can point to any type of object. You should avoid void*s like the plague, though; once you start using them you lose any and all type safety.

Upvotes: 10

Related Questions