Class++ | Classes and OOP made easy and powerful with Access Specifiers, function overloading and more!

Can you send the script here so I can take a look?

Forgot to include, I’ve updated the API Reference a little bit to show the properties in a better style.

This is the script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")

local ClassPP = require(ReplicatedStorage["Class++"])
local class = ClassPP.class


local toolClass = class "Tool" {
	
	constructor = function(self, tool)
		
		if tool and tool:IsA("Tool") then
		
			self.Tool = tool
			self.Configuration = require(self.Tool.Config) 

			self.Tool.Equipped:Connect(function()
				
				self.equipped = true
			end)
			self.Tool.Unequipped:Connect(function()
				
				self.equipped = false
			end)
		end
	end,
	Public = {
		equipped = false,
		Tool = nil,
		Configuration = {},
	}
}

CollectionService:GetInstanceAddedSignal("Tool"):Connect(function(tool)
		
	if tool:IsA("Tool") then
		
		local newTool = toolClass.new(tool)
	end
end)

This is the Error : {Class++}: This class has no member named "Tool".

I see what you mean now, this is a common mistake that people encounter when creating classes using my module.

This is mostly related on how dictionaries work in Luau, when you set a key to nil, you’re actually removing that key from the table. In this case, the key Tool is being set to nil in the Public access specifier, and since you’re setting the key Tool to nil, Lua automatically removes it from the table, which in the final classData, the Tool member does not exist.

To solve this issue, instead of setting it to nil, you can set it to false.
Here’s your updated code:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")

local ClassPP = require(ReplicatedStorage["Class++"])
local class = ClassPP.class


local toolClass = class "Tool" {
	
	constructor = function(self, tool)
		if tool and tool:IsA("Tool") then
			self.Tool = tool
			self.Configuration = require(tool.Config) 

			self.Tool.Equipped:Connect(function()
				self.equipped = true
			end)

			self.Tool.Unequipped:Connect(function()
				self.equipped = false
			end)
		end
	end,
	Public = {
		equipped = false,
		Tool = false,
		Configuration = {},
	}
}
1 Like

Oh man i didnt know this about dictionaries, thank you. :smiley:

1 Like

Release Beta 1.4.0


  • Performance improvements.
  • Fixed some bugs.
  • Updated the final method to support functions with the syntax below:
local class, final = ClassPP.class, ClassPP.final

local Test = class "Test" {
	Public = {
		test = final(function(self, ...) 
			print(self, ...)
		end),
	}	
}

A performance comparison picture between 1.3.1 and 1.4.0:

2 Likes

Release 1.0.0


Class++ is finally complete and out of beta! I can’t really think of adding any new features, so this is going to be the last version for now.
Until I get a new idea or find an efficient method to implement certain ideas that I currently have, the only updates there will ever be are performance updates and bug fixes. (And maybe some internal changes)
Thanks for using my module!

  • Updated the source code to be more efficient and clean, and removed unnecessary comments from the code.
  • Updated certain internal functions to be more performant.
  • Added a new documentation page describing how to use type checking with Class++. (It’s very useful, check it out!)
  • Fixed certain parts of the documentation.
  • Removed final functions (using the final keyword with functions), unfortunately implementing final functions required some internal changes that weren’t very worth it for this feature, so I decided to remove it altogether, you can use other methods or just use final classes instead.
    (The final keyword now works as it was in 1.3.1)

If you have any new feature ideas, or found bugs, please don’t hesitate to create a feature request or a bug form though!

2 Likes

Updated the documentation page to give a better explanation on the Type API!

Release 1.0.1


  • Members of Friend Access Specifier no longer replicate to the objects as they’re only used within the class object itself.
  • Updated the documentation.
1 Like

Release 1.1.0


  • Class++ objects now support type checking! This was an update that I was planning to do for a very long time, and it would not have been possible without @HugeCoolboy2007.
    • All of the created objects should now have type completion for the members stored in the Public access specifier.
    • Creating custom types is no longer needed, however, if you still want to use the full features of type checking in Luau, it’s still recommended that you use custom types for your classes.
    • For more info, check out this documentation page.
  • Util and Type modules now fully support the class type.
  • Updated the documentation.

(@arbitiu turns out it was possible lol.)

4 Likes

unluckiest timing :sob:, having released this barely a week ago

1 Like

Well it’s still in beta, so I think I have plenty of time to fix things up, but I didn’t know it would be this broken :sob:

My topic was somehow “moderated”, and I was saying that what you made is amazing and very underrated. Probably adding to my list.

2 Likes

Quick update: Class++ should now support Wally and Rojo!
I will make some improvements over to it in the next few days, but it should work for now. Let me know if you encounter any issues!

Wally link:

Or add this to your wally.toml file: classpp = "tenebrisnoctua/classpp@1.1.2"

Also, the documentation has been updated with a new theme!

Fixed some problems with the documentation and Wally, you should now be able to easily integrate Class++ with Wally and Rojo!

Also added a new link button on the main post for Wally.

2 Likes

Does this API use metatables? If no at all, then this is great since metatables cannot be transferred between non-module scripts as well as between client and server

Sorry, this API uses metatables. It has to because many features including Operator Overloading and Function Overloading needs to use metatables in order to function.

Though I understand your concern about metatables not being transferred over with RemoteEvents and RemoteFunctions to the Server or the Client, there are solutions such as a constructor that takes in a data table and recreates the object on the Server or the Client.

Generally OOP itself on Luau requires the usage of metatables, without them you lose a lot of power. This API functions almost the same as the Roblox Instance API, both create userdata objects with a metatable attached to them.

I hope this answers your question! If you have more, feel free to ask!

1 Like

Oh, that’s actually sad. Although, the API looks really good. I should use it in my project, probably. Thank you for answer!

1 Like

No problem! Metatables aren’t that bad actually, aside from the issue you mentioned above, the module is very well optimized! (In fact a version for the new type solver is in the works and will be released soon.)

1 Like

will the syntax be changed when the new type solver is implemented?

And how does the constructor and destructor work? when you inherit a class?

does the base class calls the constructor then the derived class’s constructor? or the derived class’s constructor is only going to be called? or which ever is which.