Equivalents were produced with the Free Edition of Instant C# (VB to C# converter) and the Free Edition of C# to C++ Converter.
Sized Array
C++ | VB.NET |
---|---|
int myArray[2]; or: int *myArray = new int[2]; |
Dim myArray(1) As Integer |
Access Array Element
C++ | VB.NET |
---|---|
x = myArray[0]; | x = myArray(0) |
Jagged Array
C++ | VB.NET |
---|---|
int **myArray = new int*[2]; | Dim myArray(1)() As Integer |
Rectangular Array
C++ | VB.NET |
---|---|
int myArray[2][3]; |
Dim myArray()() As Integer = { New Integer(2){}, New Integer(2){} } |
VB.NET | C++ |
---|---|
Public Sub method(ByRef valueTypeParam As Integer, ByRef refTypeParam As Foo) ... End Sub |
public: void method(int &valueTypeParam, Foo *&refTypeParam) { ... } |
VB.NET | C++ |
---|---|
x = CBool(y) x = CInt(y) x = CChar(y) x = CStr(y) x = CType(myObject, FooType) x = DirectCast(y, FooType) x = TryCast(myObject, FooType) |
x = static_cast<bool>(y); x = static_cast<int>(y); x = static_cast<wchar_t>(y); x = static_cast<std::wstring>(y); x = static_cast<FooType*>(myObject); x = static_cast<FooType*>(myObject); x = dynamic_cast<FooType*>(myObject); |
In VB, the keyword 'From' is used to initialize collections during construction.
VB.NET | C++ |
---|---|
' List: Dim myList As New List(Of Integer)() From {1, 2, 3} ' Dictionary: Dim myD As New Dictionary(Of String, Integer) From { {string1, 80}, {string2, 85} } |
// vector: std::vector<int> myList = {1, 2, 3}; // unordered_map: std::unordered_map<std::wstring, int> myD = { {string1, 80}, {string2, 85} }; |
Vectors (C++) and Lists (VB.NET)
C++ | VB.NET |
---|---|
#include <vector> void Vector() { std::vector<int> myList; myList.push_back(1); int i = 1; myList[0] = i; i = myList[0]; } |
Imports System.Collections.Generic Sub Vector() Dim myList As New List(Of Integer)() myList.Add(1) Dim i As Integer = 1 myList(0) = i i = myList(0) End Sub |
Maps (C++) and Dictionaries (VB.NET)
(std::map and SortedDictionary are also very close equivalents).
C++ | VB.NET |
---|---|
#include <string> #include <unordered_map> void UnorderedMap() { std::unordered_map<std::wstring, int> map; std::wstring s = L"test"; map.emplace(s, 1); int i = map[s]; i = map.size(); bool b = map.empty(); map.erase(s); } |
Imports System.Collections.Generic Sub UnorderedMap() Dim map As New Dictionary(Of String, Integer)() Dim s As String = "test" map.Add(s, 1) int i = map(s) i = map.Count Dim b As Boolean = map.Count = 0 map.Remove(s) End Sub |
Local Constant
VB.NET | C++ |
---|---|
Const myConst As Integer = 2 | constexpr int myConst = 2; |
Class Constant
VB.NET | C++ |
---|---|
Public Const myConst As Integer = 2 | public: static constexpr int myConst = 1; |
Local Variable
VB.NET | C++ |
---|---|
Dim myVar As Integer = 2 | int myVar = 2; |
Inferred Types
VB.NET | C++ |
---|---|
Option Infer On ... Dim myVar = 2 |
auto myVar = 2; |
Shared/Static Field
VB.NET | C++ |
---|---|
Public Shared S As Integer | public: static inline int S = 0; |
Read-Only Field
VB.NET | C++ |
---|---|
Public ReadOnly R1 As Integer = 2 Public ReadOnly R2 As Foo = New Foo() |
public: const int R1 = 2; Foo *const R2 = new Foo(); |
VB Static Local Variable
VB.NET | C++ |
---|---|
Sub Method() Static s As Integer s += 1 End Sub |
public: void Method() { static int s = 0; s += 1; } |
The implementation of the 'Dispose' method in the IDisposable interface can be converted to a C++ destructor, but this is not exactly equivalent.
VB.NET | C++ |
---|---|
Class Foo Implements System.IDisposable Public Sub New() Me.New(0) ' call to other constructor End Sub Public Sub New(i As Integer) End Sub Public Sub Dispose() Implements System.IDisposable.Dispose End Sub Protected Overrides Sub Finalize() ' 'finalizer' method End Sub End Class |
class Foo { public: Foo() : Foo(0) // call to other constructor { } Foo(int i) { } ~Foo() // destructor { } private: // There is no equivalent in C++ to finalizer methods: void Finalize() { } }; |
C++ | VB.NET |
---|---|
int/signed int long/long int/signed long/signed long int long long/long long int signed long long/signed long long int short/short int signed short/signed short int unsigned/unsigned int unsigned long/unsigned long int unsigned short/unsigned short int unsigned long long/unsigned long long int bool char/wchar_t signed char unsigned char float double/long double std::wstring (no C++ language built-in type) std::any (C++17) or void * (no C++ language built-in type) No C++ language or standard library equivalent No C++ language or standard library equivalent |
Integer Integer (may convert to 'Long' on some systems) Long Long Short Short UInteger UInteger (may convert to 'ULong' on some systems) UShort ULong Boolean Char SByte Byte Single Double String Object Decimal Date |
A C++ function pointer corresponds to a VB.NET delegate.
C++ | VB.NET |
---|---|
// C++11 syntax: using MyDelegate = std::function<void (int i)>; // before C++11: using MyDelegate = void (*)(int i); |
Public Delegate Sub MyDelegate(ByVal i As Integer) |
Implicitly-Typed Enum
VB.NET | C++ |
---|---|
Public Enum FormMode EditMode NewMode End Enum |
enum class FormMode { EditMode, NewMode }; |
Explicitly-Typed Enum
VB.NET | C++ |
---|---|
Public Enum FormMode As Byte EditMode NewMode End Enum |
enum class FormMode : unsigned char { EditMode, NewMode }; |
The most significant difference between VB and C++ exception handling is that C++ has no 'finally' clause.
VB.NET | C++ |
---|---|
Try ... Catch x As FooException ... Finally ... End Try |
try { ... } catch (const FooException &x) { ... } // There is no C++ equivalent to the exception 'finally' clause: //finally { ... } |
C++ doesn't have extension methods, so a VB.NET extension method is just converted to an ordinary C++ static method (calls to the method have to be adjusted to static calls using the class name).
VB.NET | C++ |
---|---|
Public Module ContainsExtension <System.Runtime.CompilerServices.Extension> _ Public Sub ExtensionMethod(ByVal myParam As String) ' ... End Sub End Module Class TestClass Private Sub TestMethod() Dim s As String = "test" s.ExtensionMethod() End Sub End Class |
#include <string> class ContainsExtension final { public: static void ExtensionMethod(const std::string &myParam) { // ... } }; class TestClass { private: void TestMethod() { std::string s = "test"; ContainsExtension::ExtensionMethod(s); } }; |
C++ | VB.NET |
---|---|
for (std::string s : StringList) { ... } |
For Each s As String In StringList ... Next s |
VB generics and C++ templates are implemented in totally different ways — VB generics is a runtime feature, while C++ templates result in separate classes created at compile-time, but you can still often achieve the same result by converting one to the other.
Creating a List
VB.NET | C++ |
---|---|
Dim myVar As New List(Of Integer) | std::vector<int> myVar; |
Creating a Dictionary
VB.NET | C++ |
---|---|
Dim myVar As New Dictionary(Of String, Integer) | std::unordered_map<std::string, int> myVar; |
Defining a Generic Class
VB.NET | C++ |
---|---|
Public Class GenericClass (Of T) End Class |
template<typename T> class GenericClass { }; |
Defining a Generic Class with a Constraint
VB.NET | C++ |
---|---|
Public Class GenericClass (Of T As SomeBase) End Class |
#include <type_traits> template<typename T> class GenericClass { static_assert(std::is_base_of<SomeBase, T>::value, "T must inherit from SomeBase"); }; |
Defining a Generic Class with a 'new' Constraint
VB.NET | C++ |
---|---|
Public Class GenericClass (Of T As New) End Class |
#include <type_traits> template<typename T> class GenericClass { static_assert(std::is_default_constructible<T>::value, "T requires default-constructible elements"); }; |
Defining a Generic Method
VB.NET | C++ |
---|---|
Public Function Compare(Of T)(param1 As T, param2 As T) As Integer | public: template<typename T> int Compare(T param1, T param2) |
Defining a Generic Method with a Constraint
VB.NET | C++ |
---|---|
Public Sub Swap(Of T As Class)(ByRef l As T, ByRef r As T) | #include <type_traits> public: template<typename T> void Swap(T &l, T &r) { static_assert(std::is_class<T>::value, "T must be a class"); } |
VB.NET | C++ |
---|---|
Imports Foo Imports Foo.Bar ' 'Bar' is a type ' namespace alias: Imports foo = SomeNamespace ' type alias: Imports bar = SomeNamespace.SomeType |
using namespace Foo; *no equivalent* // namespace alias: namespace foo = SomeNamespace; // type alias: using bar = SomeNamespace.SomeType; |
C++ | VB.NET |
---|---|
public: int &operator [](int index) { return field[index]; } *for a read-only indexer, return an int instead of an int reference (remove the '&'). |
Default Public Property Item(ByVal index As Integer) As Integer Get Return field(index) End Get Set field(index) = Value End Set End Property |
C++ | VB.NET |
---|---|
class DerivedClass : public BaseClass { public: virtual void MethodOverrideOne() override { } virtual void MethodOverrideTwo() final override { } }; |
Public Class DerivedClass Inherits BaseClass Public Overrides Sub MethodOverrideOne() End Sub Public Overrides NotOverridable Sub MethodOverrideTwo() End Sub End Class |
C++ doesn't have a separate 'interface' concept, but this is done just as easily in C++ using a class with only 'pure virtual methods'.
VB.NET | C++ |
---|---|
Public Interface IFoo Sub Method() End Interface |
class IFoo { public: // pure virtual method: virtual void Method() = 0; }; |
VB.NET | C++ |
---|---|
myVar = Function(text As String) text.Length | myVar = [&] (const std::string &text) { return text.length(); }; |
For Loop
VB.NET | C++ |
---|---|
For i As Integer = 1 To 9 Next i |
for (int i = 1; i <= 9; i++) { } |
For Each Loop
VB.NET | C++ |
---|---|
For Each s As String In StringList Next S |
for (std::string s : StringList) { } |
While Loop
VB.NET | C++ |
---|---|
Do While condition Loop or: While condition End While |
while (condition) { } |
Do While Loop
VB.NET | C++ |
---|---|
Do Loop While condition |
do { } while (condition); |
Loop Until
VB.NET | C++ (no specific 'loop until' construct) |
---|---|
Do Loop Until condition |
do { } while ( ! condition); |
Do Until
VB.NET | C++ (no specific 'do until' construct) |
---|---|
Do Until condition Loop |
while ( ! condition) { } |
VB.NET | C++ |
---|---|
Public Module Utility Public Sub UtilityMethod() ... End Sub End Module or: Public NotInheritable Class Utility Private Sub New() ' prevent instantiation End Sub Public Shared Sub UtilityMethod() ... End Sub End Class |
class Utility final { public: static void UtilityMethod() { ... } }; |
VB.NET | C++ |
---|---|
Dim s As String = "multiline string" |
std::string s = R"(multiline string)"; |
VB.NET | C++ |
---|---|
Public MustInherit Class AbstractClass Protected MustOverride Sub AbstractMethod() End Class |
class AbstractClass { protected: virtual void AbstractMethod() = 0; }; |
In C++17, the std::any type offers a good equivalent to System.Object.
VB | C++ (C++17) |
---|---|
Dim o As Object = 1 Dim i As Integer = DirectCast(o, Integer) Dim t As Type = o.GetType() |
#include <any> #include <typeinfo> std::any o = 1; int i = std::any_cast<int>(o); std::type_info t = o.type(); |
VB.NET operator overloading is similar to C++ operator overloading, except that VB.NET operator overloads are static methods while C++ operator overloads are instance methods.
C++ | VB.NET |
---|---|
class SomeType { private: int IntValue = 0; public: int operator + (const SomeType &Y) { return this->IntValue + Y.IntValue; } }; |
Public Class SomeType Private IntValue As Integer = 0 Public Shared Operator + (ByVal impliedObject As SomeType, ByVal Y As SomeType) As Integer Return impliedObject.IntValue + Y.IntValue End Operator End Class |
VB.NET | C++ |
---|---|
+, -, *, >, >=, <, <=, <<, >> & (string concatenation) () (indexing) And Or AndAlso OrElse Not Xor Mod x ^ y = Is IsNot <> If(x, y, z) If(x, y) x / y (where x and y are integers) x / y (where x and y are doubles) x \ y (where x and y are integers) x \ y (where x and y are doubles) |
unchanged + (string concatenation) [] & | && || ! or ~ (depending on context) ^ % std::pow(x, y) (no exponentiation operator) = or == (depending on context) == != != x ? y : z x != nullptr ? x : y x / static_cast<double>(y); x / y x / y |
In C++, it is more common to call them 'default parameters'.
C++ | VB.NET |
---|---|
void TestOptional(int x = 0) { ... } |
Private Sub TestOptional(Optional ByVal x As Integer = 0) ... End Sub |
C++ | VB.NET |
---|---|
Raw pointers: Foo *f1 = new Foo(); Smart pointers: std::shared_ptr<Foo> f2 = std::make_shared<Foo>(); |
Dim f1 As New Foo() Dim f2 As New Foo() |
C++ does not have properties, so you must use get/set methods instead:
VB.NET | C++ |
---|---|
Public Property IntProperty() As Integer Get Return intField End Get Set(ByVal value As Integer) intField = value End Set End Property |
public: int getIntProperty() const { return intField; } void setIntProperty(int value) { intField = value; } |
For simple cases, VB's Select construct can be converted to the C++ switch construct. However, if any of the Case statements include range or non-constant expressions, then the equivalent is an if/else block.
VB | C++ |
---|---|
' converts to switch: Select Case x Case 0 ... Case 1 ... End Select ' converts to if/else: Select Case x Case 1 To 3 ... Case Is < 10, Is > 20, Is = 15 ... End Select |
// converts to switch: switch (x) { case 0: // ... break; case 1: // ... break; } // converts to if/else: if (x >= 1 && x <= 3) { ... } else if ((x < 10) || (x > 20) || (x == 15)) { ... } |
The C++ equivalent to a VB.NET shared constructor uses a private nested class.
VB.NET | C++ |
---|---|
Class Foo Public Shared field As Integer Shared Sub New() field = 1 End Sub End Class |
class Foo { public: static inline int field = 0; private: class StaticConstructor { public: StaticConstructor() { field = 1; } }; private: static inline Foo::StaticConstructor staticConstructor; }; |
VB.NET | C++ |
---|---|
SyncLock x ... End SyncLock |
#include <mutex> ... { std::scoped_lock<std::mutex> lock(x); ...... } |
There is no direct equivalent in C++ to the VB 'TypeOf' operator, but you can replicate the behavior by testing the result of a 'dynamic_cast':
VB.NET | C++ |
---|---|
Dim b As Boolean = TypeOf f Is Foo | bool b = dynamic_cast<Foo*>(f) != nullptr; |
C++ 'typeid' is only equivalent to VB 'GetType' for template type parameters:
VB.NET | C++ |
---|---|
Private Sub method(Of T)() Dim x As Type = GetType(T) End Sub |
template<typename T> void method() { std::type_info t = typeid(T); } |
VB.NET | C++ |
---|---|
Using f As New Foo() f.method() End Using |
{ Foo *f = new Foo(); f->method(); delete f; } or, if 'Foo' is designed for RAII: { Foo f; f.method(); } |
VB.NET | C++ (omitting null handling) |
---|---|
Left(x, 2) Right(x, 2) Mid(x, 3) InStr(x, y) InStrRev(x, y) |
x.substr(0, 2) x.substr(x.length() - 2) x.substr(2) x.find(y) + 1 x.rfind(y) + 1 |
These are rarely used, but still supported.
VB.NET | C++ |
---|---|
Dim myIntegerVar% Dim myStringVar$ Dim myFloatVar! Dim myDoubleVar# |
int myIntegerVar = 0; std::string myStringVar = ""; float myFloatVar = 0; double myDoubleVar = 0; |
Copyright © 2004 – 2024 Tangible Software Solutions, Inc.