我必须对C++ 11有一个基本的误解.我的教授告诉我,除了引用或指针之外,不可能将非原始类型传递给函数.但是,以下代码工作得很好
#include <iostream>
using namespace std;
class MyClass
{
public:
int field1;
};
void print_string(string s) {
cout << s << endl;
}
void print_myclass(MyClass c) {
cout << c.field1 << endl;
}
int main(int argc, char *argv[])
{
string mystr("this is my string");
print_string(mystr); // works
MyClass m;
m.field1=9;
print_myclass(m);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
运行该程序会产生以下输出
this is my string
9
RUN SUCCESSFUL (total time: 67ms)
Run Code Online (Sandbox Code Playgroud)
我在Win7上使用MinGW/g ++
为什么这样做?我以为非原始类型不能通过值传递?!
#include<iostream>
class name
{
public:
int a;
name():a(0){};
};
void add(name * pname)
{
pname = NULL;
}
int main()
{
name varName();
name * pName = new name();
add(pName);
add(&varName);//error C2664: 'add' : cannot convert parameter 1 from 'name __cdecl *)(void)' to 'name *'
}
Run Code Online (Sandbox Code Playgroud) 在Java中,包含适当对象的所有变量实际上都是引用(即指针).因此,使用这些对象作为参数的方法调用始终是"通过引用".调用修改对象状态的方法也会影响原始对象(在调用者端).
C++是不同的:这里的参数可以通过值传递或通过引用传递.在通过值传递的对象上调用mutator方法会使原始对象不受影响.(我想按值调用会创建对象的本地副本).
所以我对此的第一反应 - 从Java到C++ - 是:当使用对象作为参数时,总是使用指针.这给了我从Java期望的行为.
但是,如果一个人不需要修改方法体中的对象,也可以使用"按值调用".是否有人想要这样做?
所以,我有一个类存储指向对象的指针.我有一个方法,可以向对象添加对象.添加时,我知道我可以通过引用或指针传递,并阅读了每个的优点和缺点,但在这种情况下,我无法弄清楚哪一个更好,为什么.对于我可以弄清楚的一切,他们几乎是一样的(但我可能错了!)
这是(一个释义)传递指针/地址:
hpp:
class Room {
vector<Item*> items;
public:
void addItem(Item*);
};
cpp:
void Room :: addItem(Item* item) {
items.push_back(item);
}
Run Code Online (Sandbox Code Playgroud)
......并通过引用传递:
hpp:
class Room {
vector<Item*> items;
public:
void addItem(Item &);
};
cpp:
void Room :: addItem(Item &item) {
items.push_back(&item);
}
Run Code Online (Sandbox Code Playgroud)
我应该使用哪个?
我正在尝试使用 C++ 来理解记忆化,并且我正在尝试用“golom 序列”做一个例子
int main(int argc, char* argv[])
{
std::unordered_map<int, int> hashTable;
int value = 7;
auto start = std::chrono::high_resolution_clock::now();
std::cout << golomS(4, hashTable) << std::endl;
auto stop = std::chrono::high_resolution_clock::now();
auto start1 = std::chrono::high_resolution_clock::now();
std::cout << golom(4) << std::endl;;
auto stop1 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(stop1 - start1);
std::cout << "Time taken by function 1: "
<< duration.count() << " microseconds" << std::endl;
std::cout << "Time taken by function 2: "
<< …Run Code Online (Sandbox Code Playgroud) 我上课了.
class Books
{
private:
int m_books;
public:
Books(int books=0)
{
m_books = books;
}
Books(const Books &source) //Here is what I don't understand.
{
m_books = source.m_books;
}
};
Run Code Online (Sandbox Code Playgroud)
我不明白为什么它必须是Books(const Books &source),而不是Books(const Books source).
在我的课堂上,我有两个方法负责获取和设置私有变量的值.在另一个类之外的方法中,我调用setter方法并将变量更改为另一个值.它暂时有效,但始终重置为原始值.
class storeItem
{
public:
void setPrice(int p)
{
price = p;
}
int getPrice()
{
return price;
}
storeItem(int p)
{
price = p;
}
private:
int price;
}
void changePrice(storeItem item)
{
int origPrice = item.getPrice();
item.setPrice(rand() % 10 + 1);
//The price is correctly changed and printed here.
cout << "This item costs " << item.getPrice() << " dollars and the price was originally " << origPrice << " dollars." << endl;
}
int main()
{
storeItem …Run Code Online (Sandbox Code Playgroud) 鉴于以下结构:
struct node
{
int data;
struct node *next;
};
Run Code Online (Sandbox Code Playgroud)
以下两个功能有什么区别:
void traverse(struct node *q);
Run Code Online (Sandbox Code Playgroud)
和
void traverse(struct node **q);
Run Code Online (Sandbox Code Playgroud)
他们是如何使用的?
我在主函数中使用它时,swap(string1,string2)将轻松交换两个字符串值,但如果我在另一个函数中使用它并从main函数调用它将无法工作!
这工作:
int main()
{
string name1="A",name2="B";
swap(name1,name2);
}
Run Code Online (Sandbox Code Playgroud)
但这个没有:
string name1="A",name2="B"; // Global Here
void exchange (string one,string two)
{
swap(one,two);
}
int main()
{
exchange(name1,name2);
}
Run Code Online (Sandbox Code Playgroud)
问题出在哪儿?
以下是从Qt应用程序中获取的代码示例.我想在"foreach"循环中编写与C++迭代器一样的循环.
DocumentWindow *MdiWindow::activeDocument()
{
return qobject_cast<DocumentWindow*>(workspace->activeWindow());
}
int i=1;
foreach( QWidget *w, workspace->windowList() ) // workspace = new QWorkspace();
{
QString text;
if( i<10 )
text = tr("&%1 %2").arg( i++ ).arg( w->windowTitle() );
else
text = w->windowTitle();
QAction *action = windowMenu->addAction( text );
action->setCheckable( true );
action->setChecked( w == activeDocument() );
connect( action, SIGNAL(triggered()), mapper, SLOT(map()) ); // mapper = new QSignalMapper( this );
mapper->setMapping( action, w );
}
Run Code Online (Sandbox Code Playgroud)
以下是我的尝试.它编译得很好,但只要在正在运行的应用程序中调用此代码就会崩溃.同时我不知道为什么.我做得对吗?
DocumentWindow *MdiWindow::activeDocument()
{
return qobject_cast<DocumentWindow*>(workspace->activeWindow());
}
int i = 1; …Run Code Online (Sandbox Code Playgroud) 将参数传递给将在短时间内调用数百万次的函数和方法时,传递所述参数的开销开始显示.
void foo(const SomeType&st){...}
对于像std :: string,std :: vector等类型...规则是通过引用传递,以便不会发生无意义的副本.然而,当处理诸如双打,英特等的POD时,故事却完全不同.
关于性能,如果函数/方法不需要改变参数,在决定是否应该通过引用,const引用或复制传递时,常见的"需要注意的事项"是什么?
void foo1(SomeType& st)
{
...
}
void foo2(const SomeType& st)
{
...
}
void foo3(SomeType st)
{
...
}
void foo4(SomeType* st)
{
...
}
Run Code Online (Sandbox Code Playgroud)
注意:这不是关于const正确性的问题.还在32/64位平台上寻找与gcc和msvc相关的答案.
一些可能相关的问答:
新手在这里,我正在阅读一些代码,我看到有时候作者在函数中使用了引用
funca (scalar& a)
// Etc
Run Code Online (Sandbox Code Playgroud)
有时他只是用
funcb (scalar a)
// Etc
Run Code Online (Sandbox Code Playgroud)
有什么不同?使用引用是一个我应该拥有的好习惯吗?
谢谢!