I'm working on converting my basic cryptocurrency miner from C# to C++ for performance reasons (I've been told that C++ is faster in many aspects). However, that aside, the focus of this post is to get some feedback for a very basic port of ReadLine
, Write
and WriteLine
as I understand them, from C# to C++. This way, I don't get too far along before learning lessons the hard way.
Console.h
From my understanding, this file is mostly meant for definitions, such as an interface
in C# in that implementation should not occur here, though it's not disallowed (unlike C# where it is disallowed):
#pragma once
#include <string>
using namespace std;
class Console
{
public:
static string ReadLine();
static void Write(string input);
static void WriteLine(string input);
};
Console.cpp
The concept of separating definition from implementation is a bit new to me (outside of interface
s and members marked as abstract
in C#). The part that threw me off here is that the static
keyword is dropped when writing out the function:
#include "Console.h"
#include <iostream>
#include <string>
using namespace std;
string Console::ReadLine() {
string result;
cin >> result;
return result;
}
void Console::Write(string input) { cout << input; }
void Console::WriteLine(string input) { cout << input + "\n"; }
CryptoSandbox.cpp
This is my entry point, I didn't really change much. I simply replaced the original cout << "Hello World"
with Console::WriteLine(...)
, which required inclusion of Console.h
to compile, so lesson learned fast there:
#include "Console.h"
#include <string>
using namespace std;
int main() {
Console::Write("Starting the crypto sandbox. Please tell us your name: ");
string userName = Console::ReadLine();
Console::WriteLine("Welcome to the crypto sandbox, " + userName + "!");
}
The goal of this post is to learn what I can simplify, and anything that can be done better. A few questions hitting me hard are:
- How does organization not become quickly overwhelming based on how VS Community creates the initial project structure?
- Why is
static
not accepted in thecpp
file when the declaration statesstatic void
in theh
file?
Outside of those two questions (entirely optional, by the way), my primary focus is certainly feedback on my port.
2 Answers 2
Don't use:
using namespace std;
In the header file it is really bad and can break code. But even in the source file is considered bad practice.
see: Why is "using namespace std;" considered bad practice?
This does not read a line:
string Console::ReadLine() {
string result;
cin >> result; // This reads a single space separated word:
return result;
}
Use std::getline()
std::string Console::ReadLine() {
std::string result;
std::getline(std::cin, result);
return result;
}
How does organization not become quickly overwhelming based on how VS Community creates the initial project structure?
I don't understand what this means.
Why is static not accepted in the cpp file when the declaration states static void in the h file?
Why waste the developers time adding in words the compiler already knows.
When transferring from one language to another a direct translation is usually not advisable. You have to use the other language in the way it is designed to be used, otherwise you are not going to get the improvements you desire.
-
1\$\begingroup\$ The answer to "why is static not accepted" can be expanded. As a rule of thumb, C++ tries to keep everything as source file only; if that is not possible, it prefers header file only; if that does not work either, the code is placed in both header and source file. "static" needs to be known at compile time, not just at link time, to know whether
Console::ReadLine
is valid code, so it has to be included in the header file. It does not have to be included in the source file too, because there can only be oneReadLine
function with that signature that is either static or non-static; not both. \$\endgroup\$Andreas T– Andreas T2021年03月15日 17:34:46 +00:00Commented Mar 15, 2021 at 17:34
If your class contains only static methods and data members, you're better off not using a class at all. Makes more sense to wrap those functions in a namespace, and you can use them just like you're using now.
namespace Console
{
std::string GetLine();
}
Your Write
functions take a string by value, which creates a copy of the string. If your string is long enough, it'll lead to another allocation and can degrade performance. Use a const reference const std::string&
or if you're using C++17, string view: std::string_view
.
Your WriteLine
functions appends a \n
to every string, which creates a new temporary string, which again might allocate. If you want to write a newline, simply append to the stream. std::cout << input << '\n';
.
C++ isn't faster just by virtue of it being C++. You really need to understand what's happening "behind-the-scenes" to take full advantage of the language.
-
1\$\begingroup\$ I don't understand how I missed the string addition. Good catch. Like the use of namespace rather than a class should have mentioned that. \$\endgroup\$Loki Astari– Loki Astari2021年03月15日 16:08:05 +00:00Commented Mar 15, 2021 at 16:08
cin
andcout
directly everywhere? \$\endgroup\$