Skip to main content

Week 1 - Starting Out

Introduction/Purpose of This Blog

About Me

Nice to meet you! My name is Aidan Grant, and I'm studying (or, depending on when you're reading this, have finished my studies in) 3D Digital Design at the Rochester Institute of Technology. I'm taking on an independent study focusing on the integration of C++ and the Unreal Engine.

I'm a technical artist/technical designer and I've really enjoyed getting into the nitty gritty of the Unreal Engine and its blueprint scripting system during my studies at RIT. As my field often deals with both the C++ and the blueprint side of Unreal, I'd like to delve into that integration and utilize its potential (as combining both makes Unreal a very powerful tool indeed).

What is This Blog?

This blog is meant to document my journey and demonstrate what I have learned. The first portion of these posts will likely consist mainly of text and a lot of bullet points as I learn information in bulk, and more photos and videos as I begin to apply that information to projects and poke around in-engine.

Covering what I've learned means I won't be restating everything word for word, but rather summarizing the interesting points and takeaways I have from the courses I'm taking. As I've had previous experience with Python and with Unreal Engine Blueprinting, I may skip over a lot of the basics that are shared across programming languages, and I'll focus on things unique to C++ (or at least things that are new to me).

Learned This Week

Overview

This week was a lot of basics! The LinkedIn Learning Course I've begun my journey with is chock-full of useful tidbits and introductory information. I've got a firm grasp on basic programming concepts, so a lot of this week has been learning how to implement and apply those concepts in C++ (and how it functions differently to Python in its understanding and execution of written code).

Key Points:

  • C++ is strongly typed
  • All .cpp files must have a main() function
  • Pointers vs references
  • The nullptr is a great way to reference nothing
  • Operators are evaluated based on operator precedence, not just on left-right order

Nitty-Gritty

Jump to:
  • C++ Essential Training LinkedIn Course - Jump to Top
    • Basic Syntax
      • What's ignored versus used by the editor
        • C++ functions not on whitespace but on relational whitespace and semicolon line terminators. all lines must be finished with a ; in order to indicate that the statement is complete.
        • the number of whitespaces between chunks of text are not important as long as there is one in between each separate part of a statement
      • All files need to have an int main() function to execute, as it is the entry point for the system when the file is run
      •  C++ is a very light language on its own and doesn't have many native functions, therefore including header files is almost always needed
      • Variables in C++ are strongly typed (declared and defined as a type, can't be changed later)
      • Variables should be initialized as soon as possible (can use braced initialization or single-line initialization)
      • Const variables - can't be changed once defined
      • Pointers versus value assignment
      • References versus pointers - references should be const to avoid accidental assignment
      • Primitive arrays function like lists in Python, but are strongly typed and cannot have different data types within them.
      • Primitive arrays also require the coder to define the length of the array along with the declaration in order to allocate the necessary memory
      • Switch case - branching conditional, very useful to avoid long if-else cascades
      • Loops
        • While vs. Do ( difference is where the condition is tested)
        •  
        • C For loops

          • made up of:
            • expression (usually a variable declaration)
            • condition to continue the for loop
            • post-loop control - happens at the end of the loop before the loop continues
          • essentially the same as a while loop
        • C++ Range-based for loop

          • is not a part of C
          • functions like a for-each loop in Unreal
          • declaration of a variable
          • choice of container
          • in each iteration of the loop, the declared variable is set to the next container element until the container is exhausted
      • Structs

        • similar to dataclasses in Python, structs in UE
        • aggregate data container
        • dot notation to access variable data after initialization
      • Functions
        • work the same as in Python, UE
        • all .cpp programs must have a main(){} function in order to start the program
        • functions must be defined as the type of data they will return - void is the only type not expected to return a value. It's more common to see int functions returning 0 for function success and other error numeric codes if an error is reached
      • Classes
        •  
        • carry variable members and function members (methods)
        • data members are private by default in declared classes
        • using the keyword "public:" and continuing the area will define things as public - most methods are public in order to be able to be accessed from the rest of the program (from what I've seen in UE C++ code this is used extremely often)
        • getters and setters should be used to change values inside of classes rather than editing them directly (as most variables should be private), which allows instances of the class to exist with differing data
      • Chapter Quiz
        •  
    • Data Types
      • Primitive data types in C++
        • Integer
        • Floating point
        • Boolean
      • Compound types
        • serve as containers for primitive types
        • things like arrays, c-strings, structs, unions, etc.
      •  Integers
        • Signed vs. Unsigned - unsigned do not set aside a bit in the memory for the sign (positive or negative)
      •  Floats and Doubles
        • Precision is sacrificed for scale in a float
        • Doubles use more bits but are more precise
        • If you need absolute precision (for applications like dealing with money), you should use integers instead and have one variable for the whole numbers and another variable for the fractionals
      • C-Strings
        • array of char variables, terminated with a 0 (null-terminator)
        •  
        • More efficient the second way
        • Utilizes character escape quotes with a backslash to display characters normally reserved for string declaration, and can also be used to display any ASCII character or a Unicode value (\' for a ', \" for a ", \\ for a \, \x40 for an @, and so on)
      • Qualifiers
        • Used before variable declaration to let the compiler know how they should be used by the program
        • Two types of qualifiers: CV (constant/volatile) and Storage Duration
          • CV Qualifiers
            • const - cannot be changed
            • mutable - can be changed
            • volatile (partly deprecated)
          • Storage Duration Qualifiers
            • static - life beyond the duration of the executable block
              • static variables defined inside of a class are used across all instances of that class - they are not stored within the class instance itself but rather persist across all instances
            • register - taken as a suggestion by the compiler, stored in processor registers (faster access)
            • extern - defined in a separate step of compilation and linked to your program later
      • References 
        • same as pass-by-ref in UE
        • references are like a copy that retains a 1-way link to the original variable, so if it is changed, the original variable changes as well
        • references are immutable once defined, and can't be uninitialized
        • should use const references as much as possible
      • Struct initialization
        • you can create objects of a struct by using braced initialization or by setting each data value individually through dot notation assignment
      • Enumerators
        • great alternative to preprocessor constants
        • allows for easy and readable switch cases
      • Unions
        • allows for the use of the same memory space for different data types
      •  Defining your own data types
        • using typedef and an existing data type will allow you to "alias" a data type
      •  Auto type
        • still strongly typed, just automatic based on the output of a function at build time
      • nullptr
        • can be automatically promoted to a pointer value of any type
      • Chapter Quiz
    • Operators
      •  Compound assignment operators
        • +=, -=, *=, /=, etc
        • convenient and safe, often more efficient
      •  Increment and decrement
        • ++ and --
        • can be used before and after a variable, using it before will pull the incremented value and return it, using it after will pull the value, increment it, then return the value - using the operator before is slightly more efficient
      • Comparison/relational operators
        • x == y will check for the value of the variables, not that the variables themselves are the same
        • conditional expressions will return a 1 for true and a 0 for false
      •  Logical operators
        • booleans in C++ are actually held as integer data - any non-zero value is true, 0 is false. If you were to set a bool variable to 7, it would evaluate to true
        • C++ can take the symbolic logical operators or the text logical operators (i.e. "&&" or "and" will work)
      • Ternary operator (?)
        • compact way of setting a value based on a conditional statement, for example:
        •  
        • will assign the value "no" to the s variable because x is not greater than y. The ternary operator will evaluate its condition (placed before the operator) and will return the value based on the evaluation (first value for true : second for false)
      • Type casting
        • converting one variable's type into another (types must be compatible)
        • the operator works on whatever is to its right, and uses the type specified, for example:

      •  Operator precedence
      • Chapter Quiz
    • Functions
      • Creating a function
        • must be declared with a return type or a "void" return type (meaning it will return nothing)
        • must be declared before it is called, but it can be defined later
        • it's common to put these declarations in a header file and import the header file to the .cpp file (this is the way that Unreal does it)
      • Passing a value to a function
        • pass-by-value is the default, meaning the value passed becomes local to the function
        • you can pass a value by reference, but it must be done explicitly
        • parameters in a function definition require a type to be declared, for example:
        • default argument values can be assigned the same way as they are in Python (i.e. int i = 5)
      • Using automatic and static variables
        • by default, variables created inside a function are local to that function and use automatic data storage
        • this can be overridden by declaring a variable as static, meaning it will persist across all calls to that function
      • Returning values from a function
        • the return type of the function must fit with the value that is returned
      • Using function pointers
        • you can declare function pointers just like you can with variables - this is helpful when determining something dynamically that would need to call a function
      • Overloading function names
        • functions in C++ don't need to have a unique name - they can be overloaded
        • the compiler will figure out which function to call based on the number and type, and order of arguments for functions that have the same name (the function's signature)
      • Defining a variable number of arguments
        • a "..." placed in the arguments of a function will be evaluated as a variadic argument, meaning any number of arguments can be passed in that area
        • the count of the arguments must be passed to the function as well (and you must use va_start and va_end) in order to tell the compiler what to do
      • Using recursion (when a function calls itself)
        • works the same way as in Python (i.e. must have at least one base case in order to stop the recursion)
      • Chapter Quiz
  • C++ for Python Programmers Runestone Course - Jump to Top
    • Chapter 1: Introduction to C++ for Python Programmers
      • While most of the information in this introductory chapter was already covered in the LinkedIn course, it's nice to be able to read out the information in a text format to help cement the concepts provided.
    • Chapter 2: Atomic C++ Data Types 
      • Secondary review of the same data types covered in the LinkedIn course
      • Helpful stress on the use of nullptr to represent nothing, similar to Python's "None"