Sign in to follow this  
SuperFist

Properties in ... VC++ - please help

Recommended Posts

SuperFist    122
Hi folks. I'm using properties in VC++ by: _declspec(property) language extension. The goal i want to achieve is something i saw in C#:
 WindowsControl.Items.Add(...);
 WindowsControl.Items[6].Text = "...";

As you can see - property "Items" can be use as single property or array of properties. How can i make something like that in C++ using _declspec ? I tried this code:
class CTest
{
private:
	vector<int> vec;

public:
	_declspec(property(get=GetVector)) vector<int> propVector;
	_declspec(property(get=GetElement)) int propVector[];

	vector<int>& GetVector()
	{ return vec; }

	int GetElement(int index)
	{ return vec[index]; }
};

but i get: "error C2371: 'CTest::propVector' : redefinition; different basic types" Lets suppose I remove: "_declspec(property(get=GetElement)) int propVector[];" from the code - becouse vector<int> have "operator[]" and i try this:
CTest Obj;
cout << Obj.propVector[3];

I get: "error C2660: 'CTest::GetVector' : function does not take 1 arguments" The proper code:
CTest Obj;
cout << Obj.propVector.operator[](3);

Question: How do it like in C# ?

Share this post


Link to post
Share on other sites
Skizz    794
Quote:

but i get: "error C2371: 'CTest::propVector' : redefinition; different basic types"

This is being generated because you have two versions of propVector (there's a clue in the error message), one is a vector<int> and the other an int[]. Call one a propVector and the other propVectorElement to sort this out.
Quote:

I get: "error C2660: 'CTest::GetVector' : function does not take 1 arguments"

The __cdecl(property (...)) is specific to VC so the rules that define how it works is totally arbitrary. It seems that the conversion from:

i=obj.property;

to

i = obj.property_getter ();

occurs before anything else (highest precedence) and that the conversion will consume trailing indexers as part of the expansion, regardless of the declaration:

i=obj.property [index];

becomes:

i=obj.property_getter (index);

even if no [] is appended to the __cdecl statement. This would explain the second error. Your solution works as it separates the [] from the property so the first expansion is used. This may also work:

i=(obj.property)[index];

although I haven't tried it.
Quote:

Question: How do it like in C# ?

The simple answer: use C#. C++ language extensions like this tend to be a bit 'hacky' since the language was never defined to have properties like the C# ones. A bit of template trickery can sort of do the job (search these forums for similar threads).

Skizz

Share this post


Link to post
Share on other sites
SuperFist    122
Hi Skizz.

Yes I know the origins of those errors. I showed them to ilustrate the problem.
But i think those VC++ properties should be cleverest.

For example:

Obj.Item[45] ...

When compiler see this code and can't find Item array property he should try overwrite it to:

Obj.Item.operator[](45)

It's a pitty that VC team didn't thought about this.

Anyway thanks for help.

Share this post


Link to post
Share on other sites
Nyarlath    104
I am not familiar with the properties, so I would "simply" define custom operators, = and [].


class Dog {
public:
Dog() : myValue(0) {}

const int operator=(int value) {
for (int i = 0; i < myCats.size(); ++i) {
myCats[i] = value;
}
return myValue = value;
}

int& operator[](int index) {
while (myCats.size() <= index) {
myCats.push_back(myValue);
}
return myCats[index];
}

private:
int myValue;
std::vector<int> myCats;
};


You can use operator = to assign a value to all the sub items, and set the default value that will be assigned to the new items.
The operator [] automatically create the object you ask for, and can be used both for read and write. If you define two operators [], one for read and one for write, you may no more need myValue;


Dog Douglas;
Douglas[2] = 3;
Douglas = 5;
Douglas[5] = 1;


Hope it helps more than switch to C#, which has to be pronounced c... s... h... i... :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this