The parent class has three properties.

public property Rows: integer read GetNumRows write SetNumRows; property Columns: integer read GetNumColumns write SetNumColumns; property All: VarMatrix read IRead write IRead; 

one of which is redefined in descendant classes:

 property All: Matrix read MRead write MRead; 

where the Matrix type is its own, for each descendant (a two-dimensional dynamic array with elements of different types ).

There are two functions that return the length and width of the matrix and two procedures, on the contrary, which define them:

 function HomerMatrix.GetNumRows:integer; begin GetNumRows := length(All); end; function HomerMatrix.GetNumColumns:integer; begin GetNumColumns := length(All[0]); end; procedure HomerMatrix.SetNumRows(NumRows:integer); begin SetLength(All, NumRows); //На эту строку ругается компилятор end; procedure HomerMatrix.SetNumColumns(NumColumns:integer); var i:integer; begin for i := 0 to Rows-1 do SetLength(All[i], NumColumns); end; 

All this disgrace is called from the class of the descendant as follows (for an integer matrix):

 constructor HomerIntMatrix.Create(h, w, def: integer); begin Rows := h; Columns := w; DefCell := def; end; 

Read the length of the array-field by property is obtained, set the length of the arrays of the second level - the same, but SetNumRows gives an error:

Can't take the address of constant expressions

If you go directly to the field

 SetLength(IRead, NumRows); 

there is no error, but I need to refer specifically to the property for the override to work.

Full code of two classes . Actually, why does this error occur, and how to get around it?

  • one
    "SetLength(All, IRead); " ??? Can SetLength(IRead, NumRows); ? - Igor
  • @Igor, yes, of course. Thanks, corrected. - Risto

1 answer 1

  1. For the compiler, accessing a property is equivalent to calling the getter function, even if this property is directly based on the class field. Using the result of a function call as a var parameter in SetLength is meaningless.

  2. However, your phrase "one of which is redefined in descendant classes," raises suspicions about the legality of your design in general. If IRead is a member of the base HomerMatrix class, and, accordingly, the property property All: VarMatrix ... also belongs to the HomerMatrix class, the fact that the heir has the property property All: Matrix ... doesn’t affect the base class, and all operations with All in the base class code will be executed for property All: VarMatrix ... , and MRead will not be affected in any way.

  3. It is necessary to deal with inheritance, virtuality and polymorphism, but for this code the question is not enough.

Looked at the code. As I thought, everything is wrong. Neither compile nor work (if you miraculously compile it) it will not. Reread point 2 above. (What does this have to do with the constructor that you mention in the comment?)

Further.

You declare the type of VarMatrix as private , and the property property All: VarMatrix ... as public . How will the external code work with this property, what type will it be represented?

The HomerIntMatrix class rewrites only one of the five abstract methods of the parent class. I remember that Delphi 7 still allowed such things (under certain conditions) - I don’t know how it is now. But the creation of objects of such classes is fraught with great trouble.

Will we continue?

  • I added the question there myself) At half of it you just answered, yes. - Risto
  • Added link to Pastebin. - Risto
  • It is compiled, just, easy, but really does not work. That is, property redefinition will work only for functions and procedures of a child class? And redefinition of functions and procedures? And then what is the deep meaning of the ability to override? I thought that if a type is used only by a property or a field of the same class, then it can be removed in private mode, since the property / field will see it, and the rest do not? I am wrong? - Risto
  • The remaining abstract methods rewrite, according to the idea, those descendant classes that use them. Trouble began when I tried to turn the array itself into a property. When working with an array as a child class field, Rows , Columns and DefCell worked. - Risto
  • It is hard for me to imagine this "working." The base class code has no idea about the property All: Matrix ... heir and cannot affect MRead . But I feel my words remain a voice crying in the wilderness. - Igor