www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Array of subclasses

reply DarkRiDDeR <baroman nm.ru> writes:
Hello. I have a class:

abstract class Addon
{
	public activate(){...}
	...
}

its children:

class A: Addon {... }
class B: Addon {... }

How do I create an array of subclasses Addon? For example, one 
could to do so:

T[2] addons = [new A(), new B()];
foreach(T addon; addons){
	addon.activate();
}
Oct 21 2015
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/21/2015 11:14 PM, DarkRiDDeR wrote:
 Hello. I have a class:

 abstract class Addon
 {
      public activate(){...}
      ...
 }

 its children:

 class A: Addon {... }
 class B: Addon {... }

 How do I create an array of subclasses Addon? For example, one could to
 do so:

 T[2] addons = [new A(), new B()];
 foreach(T addon; addons){
      addon.activate();
 }
This works: abstract class Addon { public void activate() { } } class A: Addon {} class B: Addon {} void main() { Addon[2] addons = [new A(), new B()]; } This works too: Addon[] addons = [new A(), new B()]; I am happy to report that even the following works with dmd 2.069.0-b2: auto addons = [new A(), new B()]; I think the last one used to not work. Apparently now their "common type" is inferred correctly. Ali
Oct 21 2015
parent reply DarkRiDDeR <baroman nm.ru> writes:
 This works:

 abstract class Addon {
     public void activate() {
     }
 }

 class A: Addon {}
 class B: Addon {}

 void main() {
     Addon[2] addons = [new A(), new B()];
 }

 This works too:

     Addon[] addons = [new A(), new B()];

 I am happy to report that even the following works with dmd 
 2.069.0-b2:

     auto addons = [new A(), new B()];

 I think the last one used to not work. Apparently now their 
 "common type" is inferred correctly.

 Ali
This variant works strangely. Example: abstract class Addon { public string name = "0"; } class Users: Addon { override { public string name = "USERS"; } } static final class Core { static: public Addon[] activated; public Users users; public void activate() { users = new Users; activated = [new Users, new Users]; } } Core.activate(); writeln(Core.users.name ~ "\n" ~ Core.activated[1].name); Out: USERS 0
Oct 22 2015
parent reply Maxim Fomin <mxfomin gmail.com> writes:
On Thursday, 22 October 2015 at 11:02:05 UTC, DarkRiDDeR wrote:
 This variant works strangely. Example:

 abstract class Addon
 {
 	public string name = "0";
 }
 class Users: Addon
 {
 	override
 	{
 		public string name = "USERS";
 	}
 }
 static final class Core
 {
 	static:
 		public Addon[] activated;
 		public Users users;
 		
 		public void activate()
 		{
 			users = new Users;
 			activated = [new Users, new Users];
 		}
 }

 Core.activate();
 writeln(Core.users.name ~ "\n"  ~ Core.activated[1].name);

 Out:
 USERS
 0
First of all, the code does not compile with override. It is impossible to override a data. Override should be removed. The reason it works this way is that the first access is to base class data while the second is to the derived data member.
Oct 22 2015
parent reply DarkRiDDeR <baroman nm.ru> writes:
On Thursday, 22 October 2015 at 12:24:05 UTC, Maxim Fomin wrote:
 On Thursday, 22 October 2015 at 11:02:05 UTC, DarkRiDDeR wrote:
 This variant works strangely. Example:

 abstract class Addon
 {
 	public string name = "0";
 }
 class Users: Addon
 {
 	override
 	{
 		public string name = "USERS";
 	}
 }
 static final class Core
 {
 	static:
 		public Addon[] activated;
 		public Users users;
 		
 		public void activate()
 		{
 			users = new Users;
 			activated = [new Users, new Users];
 		}
 }

 Core.activate();
 writeln(Core.users.name ~ "\n"  ~ Core.activated[1].name);

 Out:
 USERS
 0
First of all, the code does not compile with override. It is impossible to override a data. Override should be removed. The reason it works this way is that the first access is to base class data while the second is to the derived data member.
I don't need the base class data. How to create a array of subclasses objects with the derived data members?
Oct 22 2015
parent Maxim Fomin <mxfomin gmail.com> writes:
On Thursday, 22 October 2015 at 13:29:06 UTC, DarkRiDDeR wrote:
 I don't need the base class data. How to create a array of 
 subclasses objects with the derived data members?
The language is implemented in this way. You have already have the answer:
 writeln(Core.users.name)
 Out:
 USERS
Oct 22 2015
prev sibling next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 22 October 2015 at 06:14:34 UTC, DarkRiDDeR wrote:
 T[2] addons = [new A(), new B()];
Until pretty recently the compiler was a little picky about the types here so you might have to explicitly cast the first element to the base clas type. T[2] addons = [cast(T) new A(), new B()]; casting just the first element tells it you want them all to be interpreted as the base class. I believe that is fixed in the newest version.
Oct 22 2015
prev sibling parent DarkRiDDeR <baroman nm.ru> writes:
I found the following solution:

abstract class Addon
{
	public string name = "0";
	
	public void updateOfClassFields()
	{
	}
}

class Users: Addon
{
	override
	{
		public void updateOfClassFields()
		{
			name = "USERS";
		}
	}
}

activated = [new Users, new Users];
activated[1].updateOfClassFields();
writeln(Core.activated[0].name ~ "\n"  ~ Core.activated[1].name);

out:
0
USERS
Oct 22 2015