I have two classes as follows A.h contains
public ref class A
{
public:
A(void);
B ^_ObjB;
}
In A.cpp I have used methods from class B using _ObjB->Method().
Now in my class B , I have certain methods which will require methods from class A to be called so I tried to declare it in following way-
public ref class B
{
public:
B(A);
A ^_ObjA;
}
Obvious it is not right way to do it so it throwing erros. I would like to know what How can I achieve this requirement?
The same way you do in regular C++, I guess:
//A.h
public ref class B;
public ref class A
{
public:
A(void);
B ^_ObjB;
};
//B.h
public ref class A;
public ref class B
{
public:
B(A^);
A ^_ObjA;
};
Related
I have this case where I am extending from a super class with methods being typed using Generics as the following:
Models
abstract class SuperClass {
//.....
}
class SubClass extends SuperClass {
int a;
int b;
String c;
//....
}
Controllers
abstract class A {
T getDoc<T extends SuperClass>(T doc);
}
class B extends A {
T getDoc<T extends SubClass>(T doc) { //<================ Error
//....
}
}
Basically class B will only deal with a SubClass model and any class that extends it. Extending SuperClass is not enough. It's a way to enforce the type usage. I could add a helper function that will check the type for each method within class B (doc is SubClass) but seems like a lot repetition.
But the above architecture fails when overriding the method getDoc in class B saying that it isn't a valid override although SubClass is a SuperClass. How can I achieve something like this? Or is there a better way of doing it? Appreciate any pointers :)
I have finally a found a way :)
So I wanted the class B's methods to accept exclusively types that extend SubClass, but class A method's signature expects parameters extending class SuperClass.
To go about this I did the following:
Models
abstract class SuperClass {
//.....
}
class SubClass extends SuperClass {
int a;
int b;
String c;
//....
}
Controllers
abstract class A<K extends SuperClass> {
T getDoc<T extends K>(T doc);
}
class B extends A<SubClass> {
T getDoc<T extends SubClass>(T doc) {
//.......
}
}
can you use covariant modifier.
In your example:
abstract class A {
T getDoc<T extends SuperClass>(covariant T doc);
}
Check: https://github.com/dart-lang/sdk/blob/master/docs/language/informal/covariant-overrides.md
You can not narrow the generic type argument. Class B guaranties (by extending class A), that it will/can handle all type arguments (and sub types!), that class A can handle. Consider the following situation:
class OtherSubClass extends SuperClass {
//....
}
void main() {
var b = B();
b.getDoc(OtherSubClass());
}
What would you expect to happen? Class B is not able to handle objects of type OtherSubClass, so it breaks the contract with class A.
C++/CLI :
public interface class ITest{
public:
virtual void doSomething (){
}
}
public ref Base {
...........
...........
}
generic <typename T> where T : ITest
public ref Derived : Base{
public:
virtual void doNothing (){
}
}
public ref AnotherClass {
public:
generic<class T> where T : Base
static int justDoThis(){
//Problem!!
}
}
C# :
In C# there are two classes A and B. A inherits from the ITest and B inherits from Derived where A is used as the typename. Also, B has a private variable of type A. So, from main function AnotherClass.justDoThis<B>() is called where B is passed as the generic type.
"//Problem!!" Part :
Now I have to create a new instance of B in this section and also access the A which is private variable in B.
So if I take your paragraph of description of the C# code:
class A : ITest {}
class B : Derived<A>
{
private A someVariableOfTypeA;
}
class Program
{
void Main(string[] args)
{
AnotherClass.justDoThis<B>();
}
}
And the problem is that you want to do this:
public ref AnotherClass {
public:
generic<class T> where T : Base
static int justDoThis()
{
// Problem!!
Something^ actuallyB = gcnew Something();
A^ a = actuallyB->someVariableOfTypeA;
}
}
Issue #1: You can allow creation of new objects of the generic type by specifying gcnew as another generic constraint. (In C#, this would be new.) This will require that the generic type have a default (i.e., parameterless) constructor, which you can access with the normal gcnew.
generic<class T> where T : Base, gcnew
static int justDoThis()
{
T^ t = gcnew T();
}
Issue #2: You cannot access private variables within an object. That's what private means. If you want to give justDoThis access to the A object, then add an appropriate public method or property to Base. The method or property would return type ITest. You could also put that method/property on a new interface (perhaps named IHaveAnITestAccessorMethod), and add that as another generic constraint, and B satisfies all the constraints.
Note that it won't do any good to make the variable public on type B: justDoThis doesn't know about B, it only knows about T, which is a Base with a no parameter constructor.
Disclaimers:
I didn't check my syntax with a compiler.
Yes, you can do anything with reflection, but that's a bad design. Don't do that, fix your code the right way.
I'm in a method of a derived class, loosely as follows:
Class Base
{
private:
int variableIWantToAccess;
}
Class Derived : public Base
{
public someMethod() {
variableIWantToAccess++; <<-----ERROR
}
How do I access the variable that's declared in the base class? I'm unable to access it because it is private.
You should declare it as protected instead of private.
Protected members of a class are accessible for the class descendants only.
Leave the field private and create a pair of protected getter / setter methods instead (for the same reasons you wouldn't expose a public field).
Class Base
{
private:
int variableIWantToAccess;
protected:
int GetVariable() { return variableIWantToAccess; }
void SetVariable(int var) { variableIWantToAccess = var; }
}
I have a question, I have a base class and an another class which derived from the base class. Can we access derived class in the base class.
Thanks in advance
You can access the code in the derived class from the base class code, but only from within an object which is actually a derived class object, and then only if the methods involved are virtual methods.
If you have an object which is itself an instance of the base class, then from within that instance you cannot see derived class code from the base class .
example
public class Baseclass
{
public void Foo()
{
Bar();
}
public virtual void Bar()
{
print("I'm a BaseClass");
}
}
public classs Derived: BaseClass
{
public override void Bar()
{
print("I'm a Derived Class");
}
}
Main()
{
var b = new BaseClass();
x.Foo() // prints "I'm a BaseClass"
// This Foo() calls Bar() in base class
var d = new Derived();
d.Foo() // prints "I'm a Derived Class"
// in above, the code for Foo() (in BaseClass)
// is accessing Bar() in derived class
}
No you can not. If you happen to know the an object declared as the Base class is actually the derived class, you can cast it. But within the base class you can not access the derived class's members.
There are a lot of ways that a base class can access members of a derived class (depending on programming language), but generally it is considered a design smell.
Instead, you usually want the base class to only directly access its own members, and allow derived classes to override methods.
Say I have a C# interface called IMyInterface defined as follows:
// C# code
public interface IMyInterface
{
void Foo(string value);
string MyProperty { get; }
}
Assume I also have a C++/CLI class, MyConcreteClass, that implements this interface and whose header is declared as follows:
// C++/CLI header file
ref class MyConcreteClass : IMyInterface
{
public:
};
How does one implement the method Foo and the property MyProperty in the C++/CLI header?
My attempt results in the following compile error:
error C3766: 'MyConcreteClass' must
provide an implementation for the
interface method 'void
IMyInterface::Foo(System::String^
value)'
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual void __clrcall Foo(String^ value) sealed;
virtual property String^ __clrcall MyProperty
{ String^ get() sealed { String::Empty; } }
};
Interfaces need to be defined as virtual. Also note the "public IMy.." after the class decleration, it's a slighly different syntax than C#.
If you can, seal the interface members to improve performance, the compiler will be able to bind these methods more tightly than a typical virtual members.
Hope that helps ;)
I did not compile it but looks good to me... Oh and also, defining your methods as __clrcall eliminates dangers of double thunk performance penalties.
edit
the correct syntax for a property is:
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual property String^ MyProperty
{
String^ get() sealed { return String::Empty; };
void set( String^ s ) sealed { };
}
};
or, when putting the definition in the source file:
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual property String^ MyProperty
{
String^ get() sealed;
void set( String^ s ) sealed;
}
};
String^ MyConcreteClass::MyProperty::get()
{
return String::Empty;
}
void MyConcreteClass::MyProperty::set( String^ )
{
//...
}