C++ equivalent of C# OOP if(Boy b is Student) - c#

I am trying to implement the system above using C++. Previously, I am using C# and OOP to do my programs, so this will be my first time using C++ and I know there is some differences between these two languages.
What I am trying to do is I want to count number of voters in list of members from Logbook class.
In C#, i will use
foreach(Member m in _members) {
if(Member m is Voter) {
votercount++;
}
}
However, i am not sure if in cpp, this implement is correct?
In my Logbook.h file
class Logbook
{
private:
std::list<Member> _members;
In my Logbook.cpp file:
int Logbook::CandidateCount() {
int membercount;
for(Member m: _members) {
if (Member* m=dynamic_cast<const Member*>(&Candidate)) membercount++;
}
return membercount;
}
It display an error at &Candidate where it says identifier Candidate is undefined. Is it because Logbook class can't reach to Candidate class?
Any replies and help is very much appreciated.

There are a few things you are doing wrong here. First you are not initializing your counting variable so it will start off using some random value (it maybe zero or maybe something else).
Next you need to store pointers to the members of your list because in C++ polymorphism only works through pointers. If the list is responsible for deleting its elements (usual) then you should use a smart pointer like std::unique_ptr:
class Logbook {
public:
int CandidateCount();
// virtual destructor is (usually) important for polymorphic types
virtual ~Logbook() = default;
// store pointers in your list
std::list<std::unique_ptr<class Member>> members;
};
Then you can iterate through that list trying to dynamically cast each pointer to the type you want to count. If it returns a valid pointer then you know it is of that type. Otherwise a nullptr will be returned:
class Member: public Logbook {};
class Candidate: public Member {};
class Voter: public Member {};
int Logbook::CandidateCount()
{
int membercount = 0; // initialize this!!!!
for(auto& m : members) { // use reference here to avoid making a copy
if(dynamic_cast<Candidate*>(m.get()))
membercount++;
}
return membercount;
}
Note: If you want to do more than just count your candidates you can keep the pointer obtained from the dynamic cast like this:
class Candidate: public Member { public: void do_something(){} };
int Logbook::CandidateCount()
{
int membercount = 0; // initialize this!!!!
for(auto& m : members) { // use reference here to avoid making a copy
if(auto c = dynamic_cast<Candidate*>(m.get())) {
membercount++;
// c is not nullptr and is type Candidate*
c->do_something(); // use your Candidate like this
}
}
return membercount;
}

int Logbook::CandidateCount()
{
int membercount{};
for(auto const &m : _members) {
if (dynamic_cast<Member*>(m))
++membercount;
}
return membercount;
}

I would try to avoid using RTTI and dynamic_casts in C++, and instead think of a way to implement what you're doing using a different approach, namely by exploiting the OOP nature of the language.
You already have two classes that both inherit from Member, so you could just add a CountMember(int& voterCount) method that lets each member log itself in. You then just call that method for each member you have. Something like this:
class Member {
public:
virtual void countMember(int& voterCount) = 0;
};
class Candidate : public Member {
public:
void countMember(int&) override {}
};
class Voter : public Member {
public:
void countMember(int& voterCount) override {
voterCount++;
}
};
class Logbook {
private:
std::list<Member> _members;
public:
int CandidateCount() {
int votercount = 0;
for(auto& member : _members) {
member.countMember(votercount);
}
return votercount;
}
};
This makes it easy to add custom behaviors in the case new classes were to be added.

Related

Is there a way to initialize EII property within constructor?

Let's start with code from MS page:
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}
I would like to change Middle in such way, the EII property is once initialized, something like this:
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get; }
Middle()
{
ILeft.P = 0;
}
}
Above code does not compile, thus my question -- is there a syntax for doing this?
I am asking about syntax, because brute force way would be to declare private field and redirect ILeft.P getter to return data from it.
I think the only other possibility besides your suggested approach of using a backing field rather than an auto-property is to use the property initializer syntax, e.g.:
int ILeft.P { get; } = 0;
Of course with this you can't initialize based on, say, an argument passed to the constructor, so it provides only limited additional flexibility.
(There is a proposal to add "primary constructors" to the C# language, which might make it possible to initialize a get-only explicitly implemented interface property based on a constructor argument, though as far as I know there's no timeline for its inclusion in the language so I wouldn't hold your breath...)

Create class that creates another class that can be overloaded (like excel - Thisworkbook.Worksheets)

In Excel object model 'Thisworkbook' is a class that has 'Worksheets' class in it and can be overloaded with index or by sheet name. Moreover, 'Worksheets' class also has some properties/methods that can be called with/without calling the constructor (default).
E.g. MsgBox ThisWorkbook.Worksheets(1).Name '<-- by (int)
E.g. MsgBox ThisWorkbook.Worksheets("Sheet1").Name '<- by (string)
E.g. Msgbox Thisworkbook.Worksheets.Count '<- 'count property
How can I create such class in C# that has another class in it and can be overloaded?
I have tried creating a public variable of the 2nd class in the 1st class but I can only call default constructor (or other - but just one at a time)
class A
{
public B b = new B(); // <-- this is 1st constructor but how to overload ?
}
class B
{
public B() // Default Constructor
{
}
public B(int i) // Constructor 2
{
}
public B(string s) // Constructor 3
{
}
public int Count // Property
{
get { return 0; }
}
}
//------------------------------------------------------------
class Main()
{
A a = new A();
a.b.Count(); // <-- THIS WORKS
// a.b(1).Name; <-- HOW TO, USING THE SAME CLASS?
// a.b("A").Name; <-- HOW TO, USING THE SAME CLASS?
}
I know that I have not created an object array - 1 or "A" that can be returned in this example, but I just need the concept (you got it right?). I have also seen few examples using List but I really want to know how I can achieve such object hierarchy in C#... (please excuse me if this is a wrong question).
You're misunderstanding operators.
What you're seeing is the indexing operator defined on the Worksheets class.
In C#, that would be called as a.b[1] or a.b["2"].
You define it like this:
public SomeType this[int index] { get { ... } }
public SomeType this[string index] { get { ... } }

Implementing a class from 2 interfaces that share some parts

Is the following not a good practice?
public interface IMyImmutableData
{
int Data { get;}
}
public interface IMyMutableData
{
int Data { set;get;}//implements both get and set
}
public class MyData : IMyImmutableData, IMyMutableData
{
public int Data{get;set;} //implements both IMyImmutableData, IMyMutableData
}
void Main()
{
MyData myData = new MyData{Data=10};
Console.WriteLine(myData.Data);
}
The reason I ask is that resharper gives me the following warning: "possible ambiguity while accessing by this interface"
The reason I want to do the above is that when I create methods that use the MyData class, I would like to send it either as IMyMutable or IMyImmutable objects, so that users of the method know that they can expect the method to update or not update the passed in object.
I think you can ignore resharper's warning, as the ambiguity is intentional.
However, usually a wrapper class is used to provide readonly access to something, that way it can't be cast to anything that does provide more functionality.
public class MyReadonlyData : IMyReadonlyData {
private MyData instance;
public int Data {
get {
return instance.Data;
}
}
public MyReadonlyData( MyData mydata ) {
instance = mydata;
}
}
// no access to original object or setters, period.
You need to make one or both of the implementations explicit:
public int IMyImmutableData.Data { get; }
public int IMyMutableData.Data { get; set; }
When you mark one as explicit, it can only be accessed when specifically cast as that type:
MyData obj = new MyData();
obj.Data; // Doesnt exist
(obj as IMyImmutableData).Data // Exists, specifically cast as this interface
If you choose to not mark one as explicit, it will be the property chosen when cast as other appropriate types.
I think in this case your structure is fine. You don't want to explicitly implement the interfaces via separate properties, because then the Data you access via the immutable interface will actually be different than that for the mutable interface.
Also, your actual code is likely more complex, because in this case there is no ambiguity: you are accessing Data via the object itself, so interfaces need not be considered.
One solution with explicit interface implementation would be to use a common backing field, rather than auto-properties:
private int _data;
public int IMyImmutableData.Data
{
get
{
return this._data;
}
}
public int IMyMutableData.Data
{
get
{
return this._data;
}
set
{
this._data = value;
}
}
You could cast the variable and tell the compiler what exactly you mean: (resolve ambiguity)
MyData myData = new MyData{Data=10};
Console.WriteLine( ((IMyMutableData)(myData)).Data );
You need a combined interface with a "new" qualifier on the read-write interface to avoid the squawk. Further, your interfaces are poorly named. Better names would be something like "IReadableData" and "IWritableData", and "IReadWriteData". Note that while "IReadableData" does not provide any means of mutating the data, that by no stretch of the imagination implies that the data is immutable. If something is immutable it won't every be changed by anyone; that would clearly not be the case with an object of type MyData.

C# Struct / Lookup Table

Say I have a struct declared like the following:
public struct Test
{
public static int Width = 5;
...
public static int[] Value = new int[1]{ 0 };
}
Now what I want to do is call this from within another struct, but I have to clue how. What I'm trying to do would (in my mind) look like the following:
public struct AnotherStruct
{
public (type of struct) this[int key]
{
get
{
switch(key)
{
case 1:
return (another struct);
default:
return null;
}
}
}
}
My end goal is that I want to use code that looks like the following, without having to create an instance of the object:
structobject s = new AnotherStruct[5];
So this 'lookup table' will be created in another project and built, then called as a dll from my main project. Since I'm building the dll elsewhere and calling it, I'm hoping that I can get the dll loaded into memory once, and then I can just reference that memory from my main project. Then I'll have one allocated portion of memory and my code will just reference it, avoiding the need to create individual instances of this lookup table (thus avoiding the time overhead it takes to allocate the memory and store the new instance). The time I'd save would be hugely beneficial in the long run, so I'm hoping I can get this to work somehow.
I hope this isn't too confusing, but let me know if any clarification is needed.
Edit
This is being used on a website, so really I need an object that persists across all connections and is created once when the code is initially loaded. Same idea, but maybe that will make for a simpler solution?
Solution #2. Forgo the whole ID idea and just use the structure type and generics.
public struct St1
{
}
public struct St2
{
}
public class Factory<T>
where T : struct
{
static T _new = new T(); //cached copy of structure
public static T New { get { return _new; } }
}
class Program
{
static void Main(string[] args)
{
St1 x1 = Factory<St1>.New;
St1 x2 = Factory<St1>.New;
St1 x3 = Factory<St1>.New;
St2 y1 = Factory<St2>.New;
St2 y2 = Factory<St2>.New;
}
}
Solution #1. Using a common interface for all the structures and a dictionary collection
public interface IStr { }
public struct St1 : IStr
{
public static int ID = 1;
}
public struct St2 : IStr
{
public static int ID = 2;
}
public class StructFactory : System.Collections.ObjectModel.KeyedCollection<int, IStr>
{
public static StructFactory Default = new StructFactory();
protected override int GetKeyForItem(IStr item)
{
FieldInfo finfo = item.GetType().GetField("ID",
BindingFlags.Static | BindingFlags.Public);
return (int)finfo.GetValue(item);
}
public StructFactory()
{
Add(new St1());
Add(new St2());
}
}
class Program
{
static void Main(string[] args)
{
St1 x = (St1)StructFactory.Default[1];
St2 y = (St2)StructFactory.Default[2];
}
}
The syntax you use above won't work since it means "create an array of AnotherStruct with five elements in it." As mentioned in a comment, however, you really should look into using a factory pattern.
However, if you really want to use the pattern above, you could change it up slightly. Have your AnotherStruct array hold Type instances of each of your structs. Then, your "creation" line would look more like:
structobject s = (structobject)Activator.CreateInstance(AnotherStruct[5]);
You can use reflection on the Assembly (since you are wrapping it in a DLL) to get those Type objects.
And finally, unless you have a really good reason for using struct (and understand all of the nuances, of which there are several), stick with class.

Does C#/CLR contain a mechanism for marking the return values of properties as read-only / immutable?

I've been looking around, and so far haven't managed to find a good way to do this. It's a common problem, I'm sure.
Suppose I have the following:
class SomeClass : IComparable
{
private int myVal;
public int MyVal
{
get { return myVal; }
set { myVal = value; }
}
public int CompareTo(object other) { /* implementation here */ }
}
class SortedCollection<T>
{
private T[] data;
public T Top { get { return data[0]; } }
/* rest of implementation here */
}
The idea being, I'm going to implement a binary heap, and rather than only support Insert() and DeleteMin() operations, I want to support "peeking" at the highest (or lowest, as the case may be) priority value on the stack. Never did like Heisenberg, and that whole "you can't look at things without changing them" Uncertainty Principle. Rubbish!
The problem, clearly, is that the above provides no means to prevent calling code from modifying MyVal (assuming SortedCollection) via the Top property, which operation has the distinct possibility of putting my heap in the wrong order. Is there any way to prevent modifications from being applied to the internal elements of the heap via the Top property? Or do I just use the code with a warning: "Only stable if you don't modify any instances between the time they're inserted and dequeue'd. YMMV."
To answer your question: No, there's no way to implement the kind of behavior you want - as long as T is of reference type (and possibly even with some value-types)
You can't really do much about it. As long as you provide a getter, calling code can modify the internal contents of your data depending on the accessibility of said data (i.e. on properties, fields, and methods).
class SomeClass : IComparable
{
private int myVal;
public int MyVal
{
get { return myVal; }
set { myVal = value; }
}
public int CompareTo(object other) { /* implementation here */ }
}
class SortedCollection<T>
{
private T[] data;
public T Top { get { return data[0]; } }
/* rest of implementation here */
}
//..
// calling code
SortedCollection<SomeClass> col;
col.Top.MyVal = 500; // you can't really prevent this
NOTE What I mean is you can't really prevent it in the case of classes that you don't control. In the example, like others have stated you can make MyVal's set private or omit it; but since SortedColleciton is a generic class, you can't do anything about other people's structures..
You can have a readonly property (that is, a property with only a getter):
private int myVal;
public int MyVal { get { return myVal; } }
But be careful: this may not always work how you expect. Consider:
private List<int> myVals;
public List<int> MyVals { get { return myVals; } }
In this case, you can't change which List the class uses, but you can still call that List's .Add(), .Remove(), etc methods.
Your properties don't have to have the same accessibility for get/set. This covers you for anything that returns a value type (typically structs that only contain value types) or immutable reference types.
public int MyVal
{
get { return myVal; }
private set { myVal = value; }
}
For mutable reference types, you have other options, such as returning Clone()s or using ReadOnlyCollection<T> to keep the caller from changing them:
private List<int> data;
public IList<int> Data
{
get { return new ReadOnlyCollection<int>(this.data); }
}
Only implement getters for your properties and modify the collection by having add/remove methods
I understand your problem now. I think this should work:
class SortedCollection<T> where T: ICloneable
{
private T[] data;
public T Top
{
get
{
T ret = (T)data[0].Clone();
return ret;
}
}
/* rest of implementation here */
}
The ICloneable constraint ensures that the type parameter implements the ICloneable interface. (if this is acceptable)

Categories

Resources