为什么从外部访问本地声明的变量有效?
Why accessing variable declared locally from outside is working?
在树中,在接受输入时(在 takeInput
函数内),树节点是使用动态分配创建的,但我尝试静态地进行,但由于树节点是在函数内部声明的,所以它不应该工作是因为它是一个局部变量(我期待一个错误)。但为什么在那之后我还能打印它:
注意:此代码以递归方式获取输入(并且可能不是最佳方式)
#include<bits/stdc++.h>
using namespace std;
template <typename T>
class treeNode{
public:
T data;
vector <treeNode<T>> children;
treeNode(T data){
this->data=data;
}
};
treeNode<int> takeInput(){
int rootdata;
cout<<"Enter Node"<<endl;
cin>>rootdata;
// treeNode<int>* root= new treeNode<int>(rootdata);
treeNode<int> root(rootdata); //Static Allocation
cout<< "Enter Number of children of "<<rootdata<<endl;
int n;
cin>>n;
for(int i=0;i<n;i++){
treeNode<int> child = takeInput();
root.children.push_back(child);
}
return root;
}
void printTree(treeNode<int> root){
cout<<root.data<<": ";
for(int i=0;i<root.children.size();i++){
cout<<root.children[i].data<<",";
}
cout<<endl;
for(int i=0; i<root.children.size();i++){
printTree(root.children[i]);
}
}
int main(){
treeNode<int> root= takeInput();
printTree(root);
return 0;
}
以下代码使用动态分配:
#include<bits/stdc++.h>
using namespace std;
template <typename T>
class TreeNode{
public:
T data;
vector <TreeNode<T>*> children;
TreeNode(T data){
this->data=data;
}
};
TreeNode<int>* takeInput(){
int rootdata;
cout<<"Enter node"<<endl;
cin>>rootdata;
TreeNode<int>* root=new TreeNode<int>(rootdata);
cout<<"Enter number of children of "<<rootdata<<endl;
int n;
cin>>n;
for(int i=0;i<n;i++){
TreeNode<int>* child=takeInput();
root->children.push_back(child);
}
return root;
}
void printTree(TreeNode<int>* root){
if (root == NULL){
return;
}
cout<< root->data<<" :";
for(int i=0;i<root->children.size(); i++){
cout<<root->children[i]->data<<",";
}
cout<<endl;
for(int i=0;i<(*root).children.size();i++){
printTree(root->children[i]);
}
}
int main(){
TreeNode<int>* root = takeInput();
printTree(root);
return 0;
}
您的代码等同于
A foo() {
A a;
a = bar();
return a;
}
a
只是复制到 return 值(copy might be avoided 也是)。将 A
替换为 treeNode<int>
,语义保持不变。
为什么要动态代码?
我猜想使用动态分配的代码版本可能是在考虑类似
的情况下编写的
struct A {
std::vector<A> vecA;
};
是 A
的递归定义,因为当 vecA
被声明时 A
是一个不完整的类型。但这不再是这种情况了,这已正式进入 (尽管它也适用于早期版本的某些编译器),其中一些 STL 容器可以处理不完整的类型。因此它使用了形式
vector <TreeNode<T>*> children;
存储指向子节点的指针,因此存储类似于熟悉的 LinkedList 节点数据结构定义的代码
struct Node {
int data;
Node* next; // The TreeNode stores a vector of pointers instead.
};
结论
如果可能通常首选堆栈分配,因为它比堆路由更快。此外,除非使用智能指针,否则具有动态分配的代码会带来内存管理的麻烦。您的代码不需要它。使用您的示例的堆栈分配路径,让 std::vector
负责维护动态数组。
在树中,在接受输入时(在 takeInput
函数内),树节点是使用动态分配创建的,但我尝试静态地进行,但由于树节点是在函数内部声明的,所以它不应该工作是因为它是一个局部变量(我期待一个错误)。但为什么在那之后我还能打印它:
注意:此代码以递归方式获取输入(并且可能不是最佳方式)
#include<bits/stdc++.h>
using namespace std;
template <typename T>
class treeNode{
public:
T data;
vector <treeNode<T>> children;
treeNode(T data){
this->data=data;
}
};
treeNode<int> takeInput(){
int rootdata;
cout<<"Enter Node"<<endl;
cin>>rootdata;
// treeNode<int>* root= new treeNode<int>(rootdata);
treeNode<int> root(rootdata); //Static Allocation
cout<< "Enter Number of children of "<<rootdata<<endl;
int n;
cin>>n;
for(int i=0;i<n;i++){
treeNode<int> child = takeInput();
root.children.push_back(child);
}
return root;
}
void printTree(treeNode<int> root){
cout<<root.data<<": ";
for(int i=0;i<root.children.size();i++){
cout<<root.children[i].data<<",";
}
cout<<endl;
for(int i=0; i<root.children.size();i++){
printTree(root.children[i]);
}
}
int main(){
treeNode<int> root= takeInput();
printTree(root);
return 0;
}
以下代码使用动态分配:
#include<bits/stdc++.h>
using namespace std;
template <typename T>
class TreeNode{
public:
T data;
vector <TreeNode<T>*> children;
TreeNode(T data){
this->data=data;
}
};
TreeNode<int>* takeInput(){
int rootdata;
cout<<"Enter node"<<endl;
cin>>rootdata;
TreeNode<int>* root=new TreeNode<int>(rootdata);
cout<<"Enter number of children of "<<rootdata<<endl;
int n;
cin>>n;
for(int i=0;i<n;i++){
TreeNode<int>* child=takeInput();
root->children.push_back(child);
}
return root;
}
void printTree(TreeNode<int>* root){
if (root == NULL){
return;
}
cout<< root->data<<" :";
for(int i=0;i<root->children.size(); i++){
cout<<root->children[i]->data<<",";
}
cout<<endl;
for(int i=0;i<(*root).children.size();i++){
printTree(root->children[i]);
}
}
int main(){
TreeNode<int>* root = takeInput();
printTree(root);
return 0;
}
您的代码等同于
A foo() {
A a;
a = bar();
return a;
}
a
只是复制到 return 值(copy might be avoided 也是)。将 A
替换为 treeNode<int>
,语义保持不变。
为什么要动态代码?
我猜想使用动态分配的代码版本可能是在考虑类似
的情况下编写的struct A {
std::vector<A> vecA;
};
是 A
的递归定义,因为当 vecA
被声明时 A
是一个不完整的类型。但这不再是这种情况了,这已正式进入
vector <TreeNode<T>*> children;
存储指向子节点的指针,因此存储类似于熟悉的 LinkedList 节点数据结构定义的代码
struct Node {
int data;
Node* next; // The TreeNode stores a vector of pointers instead.
};
结论
如果可能通常首选堆栈分配,因为它比堆路由更快。此外,除非使用智能指针,否则具有动态分配的代码会带来内存管理的麻烦。您的代码不需要它。使用您的示例的堆栈分配路径,让 std::vector
负责维护动态数组。