CObject, CStringArray and error C2248 - arrays

class MyClass : public CObject
{
public:
MyClass();
private:
CStringArray m_myArray;
};
causes error c2248
What's wrong with this ?
I think it's related to the fact that CStringArray and MyClass both derive from CObject.
Legacy class derived from CObject currently uses CustomArray it just seems wrong to me so I would like to replace it by CStringArray.

Microsoft compiler error C2248 means "Members of a derived class cannot access private members of a base class."
I can only assume you're trying to directly reference MyClass::m_myArray from somewhere in your code, without using a public accessor function.
Update
The real answer is that the problem is caused by the copy-constructor for MyClass, attempting to copy m_myArray, but it can't, because CObject derived classes aren't copyable by default. The solution would be to write a copy constructor yourself, and rather than attempt to copy the array, copy the contents one at a time, from the source array to the destination array. Either that or use std::vector (which you should be doing anyway, as MFC containers are horrible).

You are trying to access some private member of CObject. Since both your MyClass and CStringArray derive from CObject, without more context it is impossible to know the exact problem.
The only idea that comes to mind, basically because I've fallen in the trap many times, is that CObject's copy constructor is private, so if you are trying to copy either the CStringArray or your own class, explicit or implicitly, you'll get the error.
UPDATE:
I've just taken a look at CObject's declaration and the assignment operator, too, is private. Everything else is either public or protected.

Error C2248 says "Members of a derived class cannot access private members of a base class."
CStringArray class dosn't expose Copy constructor and assignment operator, look in code for such places and replace the code with elemenet by elemnet copy.

Related

Is there a technical reason why I cannot declare a public array in a VBA class?

I just discovered that it's apparently not possible to declare a public array in a VBA class while it is fine to declare it private.
I am wondering if this is has a technical reason or if this is a design choice on Microsoft's part.
Either explanation doesn't make much sense to me: I cannot see a technical reason that would prevent a member to be private while it can be public as this is only an access check that is checked at runtime.
On the other hand, I don't understand why it shouldn't be possible to declare public arrays while it is perfectly fine to declare public integers or other data types.
I'd appreciate if someone could explain the rational behind all this.
I believe you'd need to ask the persons who created the Visual Basic (or maybe even Basic) programming language as to "why". It seems to be inherent to the languages. As far as VBA goes, the restriction comes from VB6, on which VBA bases. I find this reference in a Google search:
Declaring data as Public in a Form means you are creating a Property
on that Form, using abbreviated syntax. A Property cannot be an array
using that shortcut syntax.
To say this another way, "Public" only means "global" for
old-fashioned static (BAS) modules. For everything else Public means
something entirely different.
And this:
Instead of Arrays, You can use Collection object or Your own
Collection Class. VB6 does not allow to declare Constants, Arrays,
User Defined Types as Public.
From the VBA Help topic Constants, fixed-length strings, arrays, user-defined types, and Declare statements not allowed as Public members of an object module
Not all variables in an object module can be declared as Public.
However, procedures are Public by default, and Property procedures can
be used to simulate variables syntactically. This error has the
following causes and solutions:
Concerning arrays, specifically
You declared a Public array in an object module. Although a procedure
can't return an array, it can return a Variant that contains an array.
To simulate a Public array in a class module, use a set of Property
procedures that accept and return a Variant containing an array.

How to create a GObject final class with both public and private members?

In the chapter Boilerplate code of GObject Manual, when ViewerFile is declared as a final type using G_DECLARE_FINAL_TYPE, how can we add public data to it since it is hidden behind the viewer-file.c which is not included?
The main distinction between a "derivable" GObject type and a "final" GObject type is the visibility of the instance data structure.
If the GObject type is "derivable" then you can only use a private instance data structure, as the instance structure is public and it's generated to just include the parent's structure.
If the GObject type is "final" then you only get instance fields, since the instance data structure is private to your C source file.
You cannot mix the two approaches, unless you decide not to use the macros and write the boilerplate by hand.
Additionally, you should not ever access fields on an instance data structure; provide accessor functions, instead, so that you can validate pre-conditions and post-conditions safely.

Sub class instance variable in super-class object?

Let's say I have two classes called "SuperClass" and SubClass. SubClass extends SuperClass.
I just found out that it's not possible for SuperClass to have an instance variable of type SubClass.
That is, this will not work:
class SuperClass{
SubClass x = new SubClass();
}
because it causes the constructors to call each other, entering a perpetual loop. (because Java automatically puts in the call to Super())
Is creating a subclass instance variable impossible and a bad design idea? or is there some kind of work-around?
It is generally a bad idea. If your super class needs an instance of a subclass, that's a code smell. It creates circular dependencies and suggests a broken analysis.
The workaround/fix is usually to bring up whatever code the super class is using from the subclass into the super class.
The only restriction is in placing an allocation of the subclass (or, for that matter, another instance of the superclass) within the superclass constructor. You can most certainly have an instance field with the type of a subclass, and set it at some point after construction of the superclass. (Though you would obviously need to prevent any recursion via the setter method.)
And actually one could put the allocation in the superclass constructor if there were conditional logic in the constructor to skip the allocation if constructing the subclass. Eg:
class SuperClass {
SubClass subClassField;
SuperClass() {
if (!(this instanceof SubClass)) {
subClassField = new SubClass();
}
}
}
But, of course, just because you can do this does not say that you should. While I can imagine a few scenarios where it might be a valid approach, they would be "oddball" situations.

C# - Pass a struct to a form by reference and return value?

I have a struct:
struct Order
{
public string orderNumber;
public string orderDetail;
}
I then assign some values in Form1 and try to pass them by reference (ref) to Form2:
(Form1)
Order order = new Order();
order.orderNumber = "1234";
order.orderDetail = "Widgets";
Form2 frm2 = new Form2(ref order);
Is it possible to store the values in Form2 so that when Form2 is completed processing the values it will return the updated struct values to Form1?
In this scenario there would be a button that would close the form after validating the data.
One pattern that's sometimes useful is to define a class something like:
class Holder<T> {public T value;}
Such a class makes it possible to pass and mutate value types with code that requires reference types. Using such an approach, a routine which accepted a structure by reference and was supposed to pop up a modal dialog and fill in the structure from it, could create a Holder<thatStructType>, pass that to the form, and then copy the data from that Holder back to the passed-in reference. While in your particular scenario, it may be better to have the data-holding thing simply be a class, structures have the advantage that one can know that no outstanding references to them exist; if a routine declares a structure and passes it by reference to some outside code, then once that code returns the values in that structure won't change unless or until the routine writes them itself or passes the structure by reference to some other code. By contrast, if a routine exposes a class reference to outside code, there's no telling what that code may do with it.
Incidentally, the Holder class is also useful in a number of other scenarios. For example, if one has a Dictionary<String, Holder<Integer>> myDict, one may use Threading.Interlocked.Increment(myDict(myKey).Value)) to perform a thread-safe increment of the indicated item, much more efficiently than would be possible with a Dictionary<String, Integer>.
What I think you're asking is if Form2 can store a reference to the order structure that was passed in the constructor. The answer is no. If you want to store references, use a reference type (a class).

private static method problem

When a class is defined as a private static, why do I need to make the get and set methods static?
Because you can't return a static member from an instance method.
It seems redundant to have to mark all members in a static class as static but C# requires that you do this. It's just the way the compiler was implemented.
As far as I know there are no members that inherit any modifiers from the type by default. In other words, a public class's members are not all public by default, etc. By requiring that you mark each member as static you are explicitly laying out the contract of the type.

Resources