Author Topic: Prefix of C for C++ classes and .h/.cpp files  (Read 208 times)

Offline Vagabond

  • Sr. Member
  • ****
  • Posts: 431
Prefix of C for C++ classes and .h/.cpp files
« on: June 27, 2017, 11:29:53 PM »
I have been reading through the voldecompress code in the repository. A lot of the classes are prefixed with the letter C. Like CVolFile.

What is the C there for? I'm assuming it means something with C compatibility, but c doesn't support objects like class and struct so not sure.

Offline Arklon

  • Administrator
  • Hero Member
  • *****
  • Posts: 1128
Re: Prefix of C for C++ classes and .h/.cpp files
« Reply #1 on: June 28, 2017, 05:38:05 PM »
A lot of projects have prefix conventions. Prefixing all classes with C, typedefs with T, enums with E, etc. is one that's seen often. Another thing seen often is prefixing all pointer variables with p, class member variables with m, etc. Some major projects don't do any prefixing at all, such as LLVM.

Offline Vagabond

  • Sr. Member
  • ****
  • Posts: 431
Re: Prefix of C for C++ classes and .h/.cpp files
« Reply #2 on: June 29, 2017, 04:05:31 AM »
I feel a little dumb now. So it just means the object is a class.

Thanks Arklon.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 3914
Re: Prefix of C for C++ classes and .h/.cpp files
« Reply #3 on: June 29, 2017, 09:27:31 AM »
Pretty much, though some classes can be interfaces, in which case they'd use an I.

Note that COM relies heavily on interfaces, and the map editor C++ backend exposes its classes to the VB frontend using COM. With COM you can expect a split with the interface class I, and the implementation class C.

An interface defines a set of functions some family of classes will have; the "interface" to objects of those types. Many languages offer special support for interfaces, though in C++, it's more of a convention. By convention, an interface is a class that contains only pure virtual functions. Syntactically, they are virtual functions that have "= 0;" at the end of the function declaration. There is no corresponding function implementation. It's expected those pure functions will be implemented in derived classes.

In terms of C++ compiler checks, a class with at least one pure virtual function is called an Abstract Class. An Abstract Class can not be instantiated, only derived from. Derived classes can also be Abstract Classes as well, assuming they also contain pure virtual functions. At some point down the class hierarchy, those pure functions should be given an implementation, and only then can classes of the derived type be instantiated.


Example:
Code: [Select]
// Abstract Base Class
class Unit {
  virtual void Draw(Viewport& viewport) = 0;  // Pure virtual
};

// Building class derives from Unit
class Building : Unit {
  virtual void Draw(Viewport& viewport) {
    // Draw building, according to level of damage
    // Draw dock (maybe)
  }
};

class Vehicle : Unit {
  virtual void Draw(Viewport& viewport) {
    // Draw chasis
    // Draw turret (maybe)
    // Draw cargo (maybe)
  }
};

// Function handles objects of any type derived from Unit
void DrawUnits(Viewport& viewport) {
  // Iterate over all units, both buildings and vehicles
  for (...) {
    Unit& unit = ...;
    unit.Draw(viewport);
  }
}


Example 2:
Code: [Select]
class ArchiveReader {
  virtual long GetFileLength(char* fileName) = 0;
  // ...
}

// For reading games resources from the .vol files
class VolFile : ArchiveReader {
  // ...
}

// For reading game music from the .clm file
class ClmFile : ArchiveReader {
  // ...
}


Example 3:
Code: [Select]
class IComInterface {
  // Some generic custom interface...
}

class IComInterface2 : IComInterface {
  // Same as above, with with a few added features
  // ...
}

// Initial class implementing the interface
class ClassV1 : IComInterface {
  // ...
}

// A newer class with a few extra features
class ClassV2 : IComInterface, IComInterface2 {
  // ...
}

// Bug fix update. Unfortunately bugs in older versions became "features".
// Existing clients will continue to use old classes, new clients should use fixed behaviour
// In all cases, they have the same interface, so most client code won't know or care
class ClassV3 : IComInterface, IComInterface2 {
  // ...
}